On Mon, 2008-12-08 at 16:05 +0100, Denys Vlasenko wrote: > I built 2.6.28-rc7 + utrace and sigstep.c indeed fails. > > Here is the shortened version of sigstep.c. > Looks like when we PTRACE_SINGLESTEP after raise (SIGUSR2), > the child is left to run freely. > > (Sorry about GNU indent style... utrace-tests requires that) > > Can you confirm that it also fails for you on 2.6.28-rc7 + utrace > but works on vanilla 2.6.28-rc7?
Please also test simplified version of the second test, see below. It appears that PTRACE_SINGLESTEP is a culprit here too, no need to play with signals as in previous test, it happens without any signals. It also does not require many single-steps or forks, for me it happens on the very first iteration. (I removed the part which makes lots of forks). -- vda #include <sys/types.h> #include <sys/wait.h> #include <sys/ptrace.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <assert.h> static pid_t child; static void cleanup (void) { if (child > 0) kill (child, SIGKILL); child = 0; while (waitpid (-1, NULL, __WALL) > 0) continue; } static void handler_fail (int signo) { cleanup (); signal (SIGABRT, SIG_DFL); assert (0); } #define NUM_SINGLESTEPS 1 //#define NUM_SINGLESTEPS 10000 //#define NUM_FORKS 1 int main(int argc, char **argv) { int i, status; pid_t pid; setbuf (stdout, NULL); atexit (cleanup); signal (SIGABRT, handler_fail); signal (SIGINT, handler_fail); signal (SIGALRM, handler_fail); alarm (5); child = fork(); assert (child >= 0); if (child == 0) { /* child process */ /* endless loop for singlestepping */ while (!(child & 1)) child += 2; _exit(43); /* not reached */ } errno = 0; ptrace(PTRACE_ATTACH, child, (void *)0, (void *)0); assert(!errno); pid = waitpid(child, &status, 0); assert (pid == child); assert (WIFSTOPPED (status)); assert (WSTOPSIG (status) == SIGSTOP); for (i = 0; i < NUM_SINGLESTEPS; i++) { ptrace(PTRACE_SINGLESTEP, child, (void *)0, (void *)0); assert(!errno); /* Known bug in 2.6.28-rc7 + utrace patch: * waitpit will block, child is running freely in an endless loop */ pid = waitpid(child, &status, 0); assert (pid == child); assert (WIFSTOPPED (status)); assert (WSTOPSIG (status) == SIGTRAP); } cleanup(); return 0; }