From e8ee168344f7f6b08504e086ef1b3a2cee044f88 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Fri, 2 Jun 2023 10:07:57 +0200 Subject: [PATCH 1/4] test: clean up our mess after the pstore test --- test/units/testsuite-74.pstore.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/units/testsuite-74.pstore.sh b/test/units/testsuite-74.pstore.sh index 1b475a3f2a..9be8066e8e 100755 --- a/test/units/testsuite-74.pstore.sh +++ b/test/units/testsuite-74.pstore.sh @@ -125,6 +125,17 @@ start_pstore() { journalctl --sync } +at_exit() { + set +e + + mountpoint -q /sys/fs/pstore && umount /sys/fs/pstore + rm -fr /var/lib/systemd/pstore/* + rm -f /run/systemd/system/systemd-pstore.service.d/99-StartLimitInterval.conf + rm -f /run/systemd/pstore.conf.d/99-test.conf +} + +trap at_exit EXIT + # To avoid having to depend on the VM providing the pstore, let's simulate # it using a simple bind mount PSTORE_DIR="$(mktemp -d)" From 1326d2dd059132760b40acb7a715ecc9ff08bd35 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Fri, 2 Jun 2023 13:24:32 +0200 Subject: [PATCH 2/4] test: sync with the fake binary before killing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On faster machines we might be too fast and kill the fake binary during fork() which then makes kernel report a "wrong" binary in the coredump, e.g.: [ 31.408078] testsuite-74.sh[548]: + /tmp/make-dump /tmp/test-dump SIGTRAP [ 31.409720] testsuite-74.sh[560]: + bin=/tmp/test-dump [ 31.409720] testsuite-74.sh[560]: + sig=SIGTRAP [ 31.409720] testsuite-74.sh[560]: + ulimit -c unlimited [ 31.409720] testsuite-74.sh[560]: + pid=561 [ 31.409720] testsuite-74.sh[560]: + sleep 1 [ 31.409720] testsuite-74.sh[560]: + kill -s SIGTRAP 561 [ 31.409720] testsuite-74.sh[560]: + wait 561 [ 31.491757] systemd[1]: Created slice system-systemd\x2dcoredump.slice. [ 31.524488] systemd[1]: Started systemd-coredump@0-563-0.service. [ 31.616372] systemd-coredump[564]: [🡕] Process 561 (make-dump) of user 0 dumped core. Stack trace of thread 561: #0 0x00007ff86bb49af7 _Fork (libc.so.6 + 0xd4af7) #1 0x00007ff86bb4965f __libc_fork (libc.so.6 + 0xd465f) #2 0x000055e88011b0ad make_child (bash + 0x550ad) #3 0x000055e8800fd05f n/a (bash + 0x3705f) #4 0x000055e880100116 execute_command_internal (bash + 0x3a116) #5 0x000055e8801011f2 execute_command_internal (bash + 0x3b1f2) #6 0x000055e8801025b6 execute_command (bash + 0x3c5b6) #7 0x000055e8800f134b reader_loop (bash + 0x2b34b) #8 0x000055e8800e757d main (bash + 0x2157d) #9 0x00007ff86ba98850 n/a (libc.so.6 + 0x23850) #10 0x00007ff86ba9890a __libc_start_main (libc.so.6 + 0x2390a) #11 0x000055e8800e83b5 _start (bash + 0x223b5) ELF object binary architecture: AMD x86-64 [ 31.666617] testsuite-74.sh[560]: /tmp/make-dump: line 12: 561 Trace/breakpoint trap (core dumped) "$bin" infinity ... $ coredumpctl list --file system.journal TIME PID UID GID SIG COREFILE EXE SIZE Fri 2023-06-02 10:42:10 CEST 561 0 0 SIGTRAP journal /usr/bin/bash - Fri 2023-06-02 10:42:11 CEST 570 0 0 SIGABRT journal /tmp/test-dump - Fri 2023-06-02 10:42:12 CEST 582 0 0 SIGTRAP missing /tmp/test-dump - Fri 2023-06-02 10:42:13 CEST 593 0 0 SIGABRT missing /tmp/test-dump - --- test/units/testsuite-74.coredump.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/units/testsuite-74.coredump.sh b/test/units/testsuite-74.coredump.sh index d5039b70f4..d30fd73717 100755 --- a/test/units/testsuite-74.coredump.sh +++ b/test/units/testsuite-74.coredump.sh @@ -42,7 +42,17 @@ sig="${2:?}" ulimit -c unlimited "$bin" infinity & pid=$! -sleep 1 +# Sync with the "fake" binary, so we kill it once it's fully forked off, +# otherwise we might kill it during fork and kernel would then report +# "wrong" binary name (i.e. $MAKE_DUMP_SCRIPT instead of $CORE_TEST_BIN). +# In this case, wait until the "fake" binary (sleep in this case) enters +# the "interruptible sleep" state, at which point it should be ready +# to be sacrificed. +for _ in {0..9}; do + read -ra self_stat <"/proc/$pid/stat" + [[ "${self_stat[2]}" == S ]] && break + sleep .5 +done kill -s "$sig" "$pid" # This should always fail ! wait "$pid" From 878ec7942f02ac5169159e7748372e8c86885856 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Fri, 2 Jun 2023 16:25:06 +0200 Subject: [PATCH 3/4] coverage: add a wrapper for execvpe() It's the exactly same stuff as for execveat() - gcov doesn't have a wrapper for execvpe() so introduce our own. --- src/basic/coverage.h | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/basic/coverage.h b/src/basic/coverage.h index 3e674a8dba..2c3ff12efe 100644 --- a/src/basic/coverage.h +++ b/src/basic/coverage.h @@ -20,17 +20,16 @@ static inline _Noreturn void _coverage__exit(int status) { } #define _exit(x) _coverage__exit(x) -/* gcov provides wrappers for the exec*() calls but there's none for execveat(), - * which means we lose all coverage prior to the call. To mitigate this, let's - * add a simple execveat() wrapper in gcov's style[0], which dumps and resets - * the coverage data when needed. - * - * This applies only when we're built with -Dfexecve=true. +/* gcov provides wrappers for the exec*() calls but there's none for execveat() + * and execvpe() which means we lose all coverage prior to such call. To mitigate + * this, let's add simple wrappers in gcov's style[0] for these exec*() calls, + * which dump and reset the coverage data as needed. * * [0] https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgcc/libgcov-interface.c;h=b2ee930864183b78c8826255183ca86e15e21ded;hb=HEAD */ extern int execveat(int, const char *, char * const [], char * const [], int); +extern int execvpe(const char *, char * const [], char * const []); static inline int _coverage_execveat( int dirfd, @@ -45,3 +44,15 @@ static inline int _coverage_execveat( return r; } #define execveat(d,p,a,e,f) _coverage_execveat(d, p, a, e, f) + +static inline int _coverage_execvpe( + const char *file, + char * const argv[], + char * const envp[]) { + __gcov_dump(); + int r = execvpe(file, argv, envp); + __gcov_reset(); + + return r; +} +#define execvpe(f,a,e) _coverage_execvpe(f, a, e) From 50fb26d2379675c73fff9ecc574fb747bd7e7634 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Fri, 2 Jun 2023 16:53:45 +0200 Subject: [PATCH 4/4] test: probe a couple more paths in systemd-run --- test/units/testsuite-74.run.sh | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/test/units/testsuite-74.run.sh b/test/units/testsuite-74.run.sh index 33a8e1ebd2..cab524a0e7 100755 --- a/test/units/testsuite-74.run.sh +++ b/test/units/testsuite-74.run.sh @@ -7,17 +7,10 @@ set -o pipefail # shellcheck source=test/units/util.sh . "$(dirname "$0")"/util.sh -# FIXME(?): -# - empty ExecStart= is always inserted -# - weird results with systemd-run --property=ExecStart=false true -# - group settings for each section? -# - i.e systemd-run --remain-after-exit --on-clock-change -# --timer-property=After=systemd-journald.service true -# generates a unit that has two [Unit] and two [Timer] sections - systemd-run --help --no-pager systemd-run --version systemd-run --no-ask-password true +systemd-run --no-block --collect true export PARENT_FOO=bar touch /tmp/public-marker @@ -37,8 +30,9 @@ systemd-run --wait --pipe --slice-inherit --slice=foo \ bash -xec '[[ "$(