From: Darrick J. Wong <djwong@xxxxxxxxxx> On modern RHEL (>=8) and Debian KDE systems, systemd-coredump can be installed to capture core dumps from crashed programs. If this is the case, we would like to capture core dumps from programs that crash during the test. Set up an (admittedly overwrought) pipeline to extract dumps created during the test and then capture them the same way that we pick up "core" and "core.$pid" files. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- check | 2 ++ common/rc | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/check b/check index ce7eacb7c45d9e..77581e438c46b9 100755 --- a/check +++ b/check @@ -924,6 +924,7 @@ function run_section() $1 == "'$seqnum'" {lasttime=" " $2 "s ... "; exit} \ END {printf "%s", lasttime}' "$check.time" rm -f core $seqres.notrun + _start_coredumpctl_collection start=`_wallclock` $timestamp && _timestamp @@ -957,6 +958,7 @@ function run_section() # just "core". Use globbing to find the most common patterns, # assuming there are no other coredump capture packages set up. local cores=0 + _finish_coredumpctl_collection for i in core core.*; do test -f "$i" || continue if ((cores++ == 0)); then diff --git a/common/rc b/common/rc index 04b721b7318a7e..e4c4d05387f44e 100644 --- a/common/rc +++ b/common/rc @@ -5034,6 +5034,50 @@ _check_kmemleak() fi } +# Current timestamp, in a format that systemd likes +_systemd_now() { + timedatectl show --property=TimeUSec --value +} + +# Do what we need to do to capture core dumps from coredumpctl +_start_coredumpctl_collection() { + command -v coredumpctl &>/dev/null || return + command -v timedatectl &>/dev/null || return + command -v jq &>/dev/null || return + + sysctl kernel.core_pattern | grep -q systemd-coredump || return + COREDUMPCTL_START_TIMESTAMP="$(_systemd_now)" +} + +# Capture core dumps from coredumpctl. +# +# coredumpctl list only supports json output as a machine-readable format. The +# human-readable format intermingles spaces from the timestamp with actual +# column separators, so we cannot parse that sanely. The json output is an +# array of: +# { +# "time" : 1749744847150926, +# "pid" : 2297, +# "uid" : 0, +# "gid" : 0, +# "sig" : 6, +# "corefile" : "present", +# "exe" : "/run/fstests/e2fsprogs/fuse2fs", +# "size" : 47245 +# }, +# So we use jq to filter out lost corefiles, then print the pid and exe +# separated by a pipe and hope that nobody ever puts a pipe in an executable +# name. +_finish_coredumpctl_collection() { + test -n "$COREDUMPCTL_START_TIMESTAMP" || return + + coredumpctl list --since="$COREDUMPCTL_START_TIMESTAMP" --json=short 2>/dev/null | \ + jq --raw-output 'map(select(.corefile == "present")) | map("\(.pid)|\(.exe)") | .[]' | while IFS='|' read pid exe; do + test -e "core.$pid" || coredumpctl dump --output="core.$pid" "$pid" "$exe" &>> $seqres.full + done + unset COREDUMPCTL_START_TIMESTAMP +} + # don't check dmesg log after test _disable_dmesg_check() {