tests: add kill_child test

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/Makefile.am (check_PROGRAMS): Add kill_child.
(MISC_TESTS): Add kill_child.test.
This commit is contained in:
Eugene Syromyatnikov 2019-02-01 11:04:51 +01:00
parent 5cf7f16bad
commit cff0b9e5ca
3 changed files with 65 additions and 0 deletions

View 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 \
@ -307,6 +308,7 @@ MISC_TESTS = \
get_regs.test \
inject-nf.test \
interactive_block.test \
kill_child.test \
ksysent.test \
localtime.test \
looping_threads.test \

46
tests/kill_child.c Normal file
View File

@ -0,0 +1,46 @@
/**
* Check for a corner case that previously lead to segfault due to an attempt
* to access unitialised tcp->s_ent.
*
* 13994 ????( <unfinished ...>
* ...
* 13994 <... ???? resumed>) = ?
*/
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "tests.h"
#define ITERS 10000
#define SC_ITERS 10000
int main(void)
{
unsigned int i;
for (i = 0; i < ITERS; i++) {
int pid = fork();
if (pid < 0)
perror_msg_and_fail("fork");
if (!pid) {
unsigned int j;
for (j = 0; j < SC_ITERS; j++)
getuid();
pause();
return 0;
}
kill(pid, SIGKILL);
wait(NULL);
}
return 0;
}

17
tests/kill_child.test Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
#
# Check whether repeated killing of just forked processes crashes strace.
. "${srcdir=.}/init.sh"
run_prog "../$NAME"
# Run strace until the known corner case is observed
while :; do
run_strace -f -qq -esignal=none $args
# Printing of "<... SYSCALL resumed>" in strace.c:print_event_exit
# previously led to segfault if the syscall number hadn't been obtained
# on syscall entering.
grep -qE '^[0-9]+ <\.\.\. \?\?\?\? resumed>\) += \?$' "$LOG" && exit 0
done