On Mon, 09 Jun 2008 19:23:09 +0200, Matthew Legendre wrote: > > We're seeing issues when trying to attached to an already stopped process > on recent utrace kernels (seen on Fedora Core 8 and 9)--waitpid reports > the arrival of numerous signal 0s,
Being tracked as `stop-attach-then-wait' at: http://sourceware.org/systemtap/wiki/utrace/tests While you are right the ptrace-on-utrace emulation is currently incompatible to ptrace for proper behavior during later ptrace operations you should resume the job control stop first [attached]. It is a code from a GDB code at: http://sourceware.org/ml/gdb-patches/2008-05/msg00022.html Thanks, Jan
--- test_attached_to_stopped.c 2008-06-10 23:36:54.000000000 +0200 +++ test_attached_to_stopped-jk.c 2008-06-11 19:19:08.000000000 +0200 @@ -19,6 +19,38 @@ void stop_self() kill(getpid(), SIGSTOP); } +/* gdb/linux-nat.c */ +/* Detect `T (stopped)' in `/proc/PID/status'. + Other states including `T (tracing stop)' are reported as false. */ + +static int +pid_is_stopped (pid_t pid) +{ + FILE *status_file; + char buf[100]; + int retval = 0; + + snprintf (buf, sizeof (buf), "/proc/%d/status", (int) pid); + status_file = fopen (buf, "r"); + if (status_file != NULL) + { + int have_state = 0; + + while (fgets (buf, sizeof (buf), status_file)) + { + if (strncmp (buf, "State:", 6) == 0) + { + have_state = 1; + break; + } + } + if (have_state && strstr (buf, "T (stopped)") != NULL) + retval = 1; + fclose (status_file); + } + return retval; +} + int attach_then_run(void (*func)(void)) { int pid, result; @@ -32,6 +64,28 @@ int attach_then_run(void (*func)(void)) perror("Ptrace attach error"); exit(-1); } + if (pid_is_stopped(pid)) { + /* gdb/linux-nat.c */ + + /* The process is definitely stopped. It is in a job control + stop, unless the kernel predates the TASK_STOPPED / + TASK_TRACED distinction, in which case it might be in a + ptrace stop. Make sure it is in a ptrace stop; from there we + can kill it, signal it, et cetera. + + First make sure there is a pending SIGSTOP. Since we are + already attached, the process can not transition from stopped + to running without a PTRACE_CONT; so we know this signal will + go into the queue. The SIGSTOP generated by PTRACE_ATTACH is + probably already in the queue (unless this kernel is old + enough to use TASK_STOPPED for ptrace stops); but since SIGSTOP + is not an RT signal, it can only be queued once. */ + kill (pid, SIGSTOP); /* tgkill() is required for threads! */ + + /* Finally, resume the stopped process. This will deliver the SIGSTOP + (or a higher priority signal, just like normal PTRACE_ATTACH). */ + ptrace (PTRACE_CONT, pid, 0, 0); + } return pid; }