]> granicus.if.org Git - strace/commitdiff
tests: add kill_child test
authorEugene Syromyatnikov <evgsyr@gmail.com>
Fri, 1 Feb 2019 10:04:51 +0000 (11:04 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 11 Feb 2019 23:35:07 +0000 (23:35 +0000)
This tests repeatedly creates and kills children, so some corner
cases in handling of not-quite-existing processes can be observed.

Previously, strace was crashing in the following situation:

    13994 ????( <unfinished ...>
    ...
    13994 <... ???? resumed>) = ?

as tcp->s_ent wasn't initialised on syscall entering and
strace.c:print_event_exit segfaulted when tried to access
tcp->s_ent->sys_name.

* tests/kill_child.c: New file.
* tests/kill_child.test: New test.
* tests/.gitignore: Add kill_child.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(MISC_TESTS): Add kill_child.test.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
tests/.gitignore
tests/Makefile.am
tests/kill_child.c [new file with mode: 0644]
tests/kill_child.test [new file with mode: 0755]

index 24b1701774b5197bd4df017451deb0d1a2974a65..eb08d8f98d968d25f97f10e4aafc7012ee985bbf 100644 (file)
@@ -209,6 +209,7 @@ keyctl-Xabbrev
 keyctl-Xraw
 keyctl-Xverbose
 kill
+kill_child
 ksysent
 ksysent.h
 lchown
index cf2b8b832b0226766858b33334ce77b59afb1add..d354695df72e989f151d4865b5a437214b6a863d 100644 (file)
@@ -106,6 +106,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
        ioctl_perf-success \
        ioctl_rtc-v \
        is_linux_mips_n64 \
+       kill_child \
        ksysent \
        list_sigaction_signum \
        localtime \
@@ -305,6 +306,7 @@ MISC_TESTS = \
        get_regs.test \
        inject-nf.test \
        interactive_block.test \
+       kill_child.test \
        ksysent.test \
        localtime.test \
        opipe.test \
diff --git a/tests/kill_child.c b/tests/kill_child.c
new file mode 100644 (file)
index 0000000..55b83ab
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Check for the corner case that previously lead to segfault
+ * due to an attempt to access unitialised tcp->s_ent.
+ *
+ * 13994 ????( <unfinished ...>
+ * ...
+ * 13994 <... ???? resumed>) = ?
+ *
+ * Copyright (c) 2019 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+
+#include <sched.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#define ITERS    10000
+#define SC_ITERS 10000
+
+int
+main(void)
+{
+       volatile sig_atomic_t *const mem =
+               mmap(NULL, get_page_size(), PROT_READ | PROT_WRITE,
+                    MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+       if (mem == MAP_FAILED)
+               perror_msg_and_fail("mmap");
+
+       for (unsigned int i = 0; i < ITERS; ++i) {
+               mem[0] = mem[1] = 0;
+
+               const pid_t pid = fork();
+               if (pid < 0)
+                       perror_msg_and_fail("fork");
+
+               if (!pid) {
+                       /* wait for the parent */
+                       while (!mem[0])
+                               ;
+                       /* let the parent know we are running */
+                       mem[1] = 1;
+
+                       for (unsigned int j = 0; j < SC_ITERS; j++)
+                               sched_yield();
+
+                       pause();
+                       return 0;
+               }
+
+               /* let the child know we are running */
+               mem[0] = 1;
+               /* wait for the child */
+               while (!mem[1])
+                       ;
+
+               if (kill(pid, SIGKILL))
+                       perror_msg_and_fail("kill");
+               if (wait(NULL) != pid)
+                       perror_msg_and_fail("wait");
+       }
+
+       return 0;
+}
diff --git a/tests/kill_child.test b/tests/kill_child.test
new file mode 100755 (executable)
index 0000000..312592b
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Check whether repeated killing of just forked processes crashes strace.
+#
+# Copyright (c) 2019 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+run_prog_skip_if_failed date +%s > /dev/null
+s0="$(date +%s)"
+
+run_prog
+args="-f -qq -e signal=none -e trace=sched_yield,/kill $args"
+
+# Run strace until the known corner case is observed.
+while :; do
+       run_strace $args
+
+       # Printing of "<... SYSCALL resumed>" in strace.c:print_event_exit
+       # used to segfault when the syscall number had not been obtained
+       # on syscall entering.
+       grep -q '^[1-9][0-9]* <\.\.\. ???? resumed>) \+= ?$' "$LOG" && exit 0
+
+       s1="$(date +%s)"
+       if [ "$(($s1-$s0))" -gt "$(($TIMEOUT_DURATION/2))" ]; then
+               skip_ 'Unable to reproduce <... ???? resumed>'
+       fi
+done