From: Dmitry V. Levin Date: Tue, 9 Feb 2016 04:16:41 +0000 (+0000) Subject: tests: check that -f -p attaches to threads properly X-Git-Tag: v4.12~572 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6204654329df64101f3e6c2ea8815eb36550ec2e;p=strace tests: check that -f -p attaches to threads properly Check that -f -p attaches and follows all threads of the given pid. * tests/attach-f-p.c: New file. * tests/attach-f-p.test: New test. * tests/.gitignore: Add attach-f-p. * tests/Makefile.am (check_PROGRAMS): Likewise. (attach_f_p_LDADD): New variable. (TESTS): Add attach-f-p.test. --- diff --git a/tests/.gitignore b/tests/.gitignore index 690242e2..c5dd3cb7 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -8,6 +8,7 @@ _newselect adjtimex aio +attach-f-p attach-p-cmd-cmd attach-p-cmd-p bpf diff --git a/tests/Makefile.am b/tests/Makefile.am index a28a46aa..7efbf77a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -58,6 +58,7 @@ check_PROGRAMS = \ _newselect \ adjtimex \ aio \ + attach-f-p \ attach-p-cmd-cmd \ attach-p-cmd-p \ bpf \ @@ -172,6 +173,7 @@ check_PROGRAMS = \ xettimeofday \ # end of check_PROGRAMS +attach_f_p_LDADD = -lrt -lpthread $(LDADD) clock_xettime_LDADD = -lrt $(LDADD) filter_unavailable_LDADD = -lpthread $(LDADD) fstat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64 @@ -311,6 +313,7 @@ TESTS = \ xettimeofday.test \ \ count.test \ + attach-f-p.test \ attach-p-cmd.test \ detach-sleeping.test \ detach-stopped.test \ diff --git a/tests/attach-f-p.c b/tests/attach-f-p.c new file mode 100644 index 00000000..51a53336 --- /dev/null +++ b/tests/attach-f-p.c @@ -0,0 +1,137 @@ +/* + * This file is part of attach-f-p strace test. + * + * Copyright (c) 2016 Dmitry V. Levin + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#define N 3 + +typedef union { + void *ptr; + pid_t pid; +} retval_t; + +typedef struct { + sigset_t set; + unsigned int no; +} thread_arg_t; + +static const char text_parent[] = "attach-f-p.test parent"; +static const char *child[N] = { + "attach-f-p.test child 0", + "attach-f-p.test child 1", + "attach-f-p.test child 2" +}; +static const int sigs[N] = { SIGALRM, SIGUSR1, SIGUSR2 }; +static const struct itimerspec its[N] = { + { .it_value.tv_nsec = 500000000 }, + { .it_value.tv_nsec = 700000000 }, + { .it_value.tv_nsec = 900000000 }, +}; +static thread_arg_t args[N] = { + { .no = 0 }, + { .no = 1 }, + { .no = 2 } +}; + +static void * +thread(void *a) +{ + thread_arg_t *arg = a; + int signo; + errno = sigwait(&arg->set, &signo); + if (errno) + perror_msg_and_fail("sigwait"); + assert(chdir(child[arg->no]) == -1); + retval_t retval = { .pid = syscall(__NR_gettid) }; + return retval.ptr; +} + +int +main(void) +{ + pthread_t t[N]; + unsigned int i; + + for (i = 0; i < N; ++i) { + sigemptyset(&args[i].set); + sigaddset(&args[i].set, sigs[i]); + + errno = pthread_sigmask(SIG_BLOCK, &args[i].set, NULL); + if (errno) + perror_msg_and_fail("pthread_sigmask"); + } + + for (i = 0; i < N; ++i) { + struct sigevent sev = { + .sigev_notify = SIGEV_SIGNAL, + .sigev_signo = sigs[i] + }; + timer_t timerid; + if (timer_create(CLOCK_MONOTONIC, &sev, &timerid)) + perror_msg_and_skip("timer_create"); + + if (timer_settime(timerid, 0, &its[i], NULL)) + perror_msg_and_fail("timer_settime"); + + errno = pthread_create(&t[i], NULL, thread, (void *) &args[i]); + if (errno) + perror_msg_and_fail("pthread_create"); + } + + if (write(3, "\n", 1) != 1) + perror_msg_and_fail("write"); + + for (i = 0; i < N; ++i) { + retval_t retval; + errno = pthread_join(t[i], &retval.ptr); + if (errno) + perror_msg_and_fail("pthread_join"); + errno = ENOENT; + printf("%-5d chdir(\"%s\") = -1 ENOENT (%m)\n" + "%-5d +++ exited with 0 +++\n", + retval.pid, child[i], retval.pid); + } + + pid_t pid = getpid(); + assert(chdir(text_parent) == -1); + + printf("%-5d chdir(\"%s\") = -1 ENOENT (%m)\n" + "%-5d +++ exited with 0 +++\n", pid, text_parent, pid); + + return 0; +} diff --git a/tests/attach-f-p.test b/tests/attach-f-p.test new file mode 100755 index 00000000..ecae25fc --- /dev/null +++ b/tests/attach-f-p.test @@ -0,0 +1,51 @@ +#!/bin/sh +# +# Check that -f -p attaches to threads properly. +# +# Copyright (c) 2016 Dmitry V. Levin +# 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" + +# strace -f -p is implemented using /proc/$pid/task/ +[ -d /proc/self/task/ ] || + framework_skip_ '/proc/self/task/ is not available' +run_prog_skip_if_failed \ + kill -0 $$ +run_prog ./attach-f-p > /dev/null 3>&1 + +OUT="$LOG.out" +EXP="$LOG.exp" +./set_ptracer_any sh -c "exec ./attach-f-p > $EXP 3> $OUT" > /dev/null & +tracee_pid=$! + +while ! [ -s "$OUT" ]; do + kill -0 $tracee_pid 2> /dev/null || + fail_ 'set_ptracer_any sleep failed' +done + +run_strace -a32 -f -echdir -esignal=none -p $tracee_pid +match_diff "$LOG" "$EXP" +rm -f "$EXP" "$OUT"