tests: check tracing of looping threads

* test/many_looping_threads.c: Remove.
* test/.gitignore: Remove many_looping_threads.
* test/Makefile (PROGS): Likewise.
(many_looping_threads): Remove.
* tests/looping_threads.c: New file.
* tests/looping_threads.test: New test.
* tests/.gitignore: Add looping_threads.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(looping_threads_LDADD): New variable.
(MISC_TESTS, XFAIL_TESTS): Add looping_threads.test.
This commit is contained in:
Дмитрий Левин 2018-07-04 02:11:27 +00:00 committed by Eugene Syromyatnikov
parent 2c8b6de913
commit c1838de552
7 changed files with 154 additions and 55 deletions

1
test/.gitignore vendored
View File

@ -1,7 +1,6 @@
childthread
clone
leaderkill
many_looping_threads
mmap_offset_decode
mtd
seccomp

View File

@ -3,8 +3,7 @@ CFLAGS += -Wall
PROGS = \
sig skodic clone leaderkill childthread \
sigkill_rain wait_must_be_interruptible threaded_execve \
mtd ubi seccomp sfd mmap_offset_decode x32_lseek x32_mmap \
many_looping_threads
mtd ubi seccomp sfd mmap_offset_decode x32_lseek x32_mmap
all: $(PROGS)
@ -12,8 +11,6 @@ leaderkill: LDFLAGS += -pthread
childthread: LDFLAGS += -pthread
many_looping_threads: LDFLAGS += -pthread
clean distclean:
rm -f *.o core $(PROGS) *.gdb

View File

@ -1,49 +0,0 @@
// This testcase, when run with large number of threads
// under stace -f, may never finish because strace does not
// ensure any fairness in thread scheduling:
// it restarts threads as they stop. If daughter threads crowd out
// the "mother" and _they_ get continually restarted by strace,
// the end of spawning loop will never be reached.
//
// Also, it is a testcase which triggers the
// "strace: Exit of unknown pid 32457 seen"
// message when on testcase exit, strace sees deaths of newly-attached
// threads _before_ their first syscall stop.
//
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
static int thd_no;
static void *sub_thd(void *c)
{
dprintf(1, "sub-thread %d created\n", ++thd_no);
for (;;)
getuid();
return NULL;
}
int main(int argc, char *argv[])
{
int i;
pthread_t *thd;
int num_threads = 1;
if (argv[1])
num_threads = atoi(argv[1]);
thd = malloc(num_threads * sizeof(thd[0]));
dprintf(1, "test start, num_threads:%d...\n", num_threads);
for (i = 0; i < num_threads; i++) {
pthread_create(&thd[i], NULL, sub_thd, NULL);
dprintf(1, "after pthread_create\n");
}
/* Exit. This kills all threads */
return 0;
}

1
tests/.gitignore vendored
View File

@ -220,6 +220,7 @@ list_sigaction_signum
llseek
localtime
lookup_dcookie
looping_threads
lseek
lstat
lstat64

View File

@ -109,6 +109,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
ksysent \
list_sigaction_signum \
localtime \
looping_threads \
mmsg-silent \
mmsg_name-v \
msg_control-v \
@ -172,6 +173,7 @@ fstat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
fstatat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
ftruncate64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
localtime_LDADD = $(clock_LIBS) $(LDADD)
looping_threads_LDADD = -lpthread $(LDADD)
lstat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
mmap64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
mmap64_Xabbrev_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
@ -307,6 +309,7 @@ MISC_TESTS = \
interactive_block.test \
ksysent.test \
localtime.test \
looping_threads.test \
opipe.test \
options-syntax.test \
pc.test \
@ -348,7 +351,8 @@ TESTS = $(GEN_TESTS) $(DECODER_TESTS) $(MISC_TESTS) $(STACKTRACE_TESTS)
XFAIL_TESTS_ =
XFAIL_TESTS_m32 = $(STACKTRACE_TESTS)
XFAIL_TESTS_mx32 = $(STACKTRACE_TESTS)
XFAIL_TESTS = $(XFAIL_TESTS_$(MPERS_NAME)) $(XFAIL_TESTS_$(ARCH))
XFAIL_TESTS = $(XFAIL_TESTS_$(MPERS_NAME)) $(XFAIL_TESTS_$(ARCH)) \
looping_threads.test
TEST_LOG_COMPILER = env
AM_TEST_LOG_FLAGS = STRACE_ARCH=$(ARCH) STRACE_NATIVE_ARCH=$(NATIVE_ARCH) \

110
tests/looping_threads.c Normal file
View File

@ -0,0 +1,110 @@
/*
* Check tracing of looping threads.
*
* Copyright (c) 2009-2018 The strace developers.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "tests.h"
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
static void *
thread(void *arg)
{
for (;;)
getuid();
return arg;
}
int
main(int ac, const char *av[])
{
assert(ac == 3);
int timeout = atoi(av[1]);
assert(timeout > 0);
int num_threads = atoi(av[2]);
assert(num_threads > 0);
/* Create a new process group. */
if (setpgid(0, 0))
perror_msg_and_fail("setpgid");
/*
* When the main process terminates, the process group becomes orphaned.
* If any member of the orphaned process group is stopped, then
* a SIGHUP signal followed by a SIGCONT signal is sent to each process
* in the orphaned process group.
* Create a process in a stopped state to activate this behaviour.
*/
pid_t stopped = fork();
if (stopped < 0)
perror_msg_and_fail("fork");
if (!stopped) {
raise(SIGSTOP);
_exit(0);
}
const sigset_t set = {};
const struct sigaction act = { .sa_handler = SIG_DFL };
if (sigaction(SIGALRM, &act, NULL))
perror_msg_and_fail("sigaction");
if (sigprocmask(SIG_SETMASK, &set, NULL))
perror_msg_and_fail("sigprocmask");
alarm(timeout);
/*
* Create all threads in a subprocess, this guarantees that
* their tracer will not be their parent.
*/
pid_t pid = fork();
if (pid < 0)
perror_msg_and_fail("fork");
if (!pid) {
for (int i = 0; i < num_threads; i++) {
pthread_t t;
if ((errno = pthread_create(&t, NULL, thread, NULL)))
perror_msg_and_fail("pthread_create #%d", i);
}
/* This terminates all threads. */
_exit(0);
}
int s;
if (waitpid(pid, &s, 0) != pid)
perror_msg_and_fail("waitpid");
assert(WIFEXITED(s));
return WEXITSTATUS(s);
}

37
tests/looping_threads.test Executable file
View File

@ -0,0 +1,37 @@
#!/bin/sh
#
# Check tracing of looping threads.
#
# Copyright (c) 2009-2018 The strace developers.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
. "${srcdir=.}/init.sh"
check_prog nproc
timeout="$(($TIMEOUT_DURATION/10))"
nproc="$((64+$timeout+$(nproc)))"
run_prog "../$NAME" "$timeout" "$nproc"
run_strace -f -qq -enone -esignal=none $args