On Mon, 05 Oct 2009 21:00:37 +0200, Oleg Nesterov wrote: > On 10/05, Jan Kratochvil wrote: > > > > On Mon, 05 Oct 2009 04:51:32 +0200, Oleg Nesterov wrote: > > > Currently, if a tracer does ptrace(DETACH, tracee, SIGXXX) > > > and then another/same tracer does ptrace(ATTACH, tracee) > > > then SIGXXX will not be reported to the new tracer. > > > > > > Why? > > > > Naive programs expect the first signal after PTRACE_ATTACH will be SIGSTOP. > > They should not, this is just wrong.
That may be a right point but such programs are in use out there. Sure if it would be a real difficulty one can keep it as-is as GDB-7.0 soon to be released has it already fixed, strace works with it. Still ltrace crashes the inferior in such case. > And I think the proposed change doesn't change the behaviour > in this sense. We started to discuss two different changes: my asked for one: ptrace(DETACH, SIGSTOP) should leave the tracee stopped. a new one: First signal after PTRACE_ATTACH should be SIGSTOP. I find the latter as a lower priority, it just was brought in as a part of the discussion. I am not aware the latter would be any time filed as a real Bug. > > > It is not trivial to implement, and I don't understand why > > > it is important to keep this behaviour. But we have the test > > > case which checks this: attach-into-signal. > > > > This testcase is in fact PASSing even when non-SIGSTOP signal is sent as the > > first one after PTRACE_ATTACH. It has specific handling of such cases. > > This test-case also does: > > /* detach with SIGPIPE/attach. This should kill tracee */ > ptrace (PTRACE_DETACH, child, (void *) 1, (void *) SIGPIPE); > > ptrace (PTRACE_ATTACH, child, (void *) 0, (void *) 0); > > waitpid (child, &status, 0); > assert (WIFSIGNALED (status) && WTERMSIG (status) == SIGPIPE); > > It fails if the second PTRACE_ATTACH sees SIGPIPE. This is what > I can't understand. attach-info-signal from the ptrace-testsuite does not FAIL for me. Which kernel version does it FAIL on for you? > > > Could you explain what can be breaked if SIGXXX will be reported > > > to the next tracer (assuming the 2nd ATTACH is fast enough) ? > > > > With a testcase looping in: void handler(int sig) { raise(sig); }: > > the latest official GDB release (6.8) will: > > > > Attaching to process 5412 > > linux-nat.c:988: internal-error: linux_nat_attach: Assertion `pid == GET_PID > > (inferior_ptid) && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP' > > failed. > > A problem internal to GDB has been detected, > > further debugging may prove unreliable. > > Quit this debugging session? (y or n) y > > Hmm. Could you please explain what "testcase looping" above mean? Attached. > Perhaps we don't understand each other... > > OK. Currently, ptrace(DETACH, SIGXXX) means: > > - untrace > > - the tracee will get this SIGXXX and handle this signal > > - BUT! if the new tracer attaches right now, before the > tracee handles the signal, this signal will not be > reported to the new tracer. > > With the current utrace-ptrace implementation: if the second > attach happens before the tracee dequeues SIGXXX, this signal > will be reported to the new tracer too. I think you are discussing the latter Bug (first signal received by a tracer after PTRACE_ATTACH should be SIGSTOP) while I was asking about the former Bug (PTRACE_DETACH(SIGSTOP) should leave tracee stopped), do you agree? Thanks, Jan
#include <stdio.h> #include <signal.h> #include <string.h> #include <assert.h> #define SIGNAL SIGALRM static void handler (int sig) { raise (sig); } int main (void) { struct sigaction act; int i; memset (&act, 0, sizeof (struct sigaction)); act.sa_handler = handler; act.sa_flags = SA_RESTART; i = sigaction (SIGNAL, &act, 0); assert (i == 0); i = raise (SIGNAL); assert (i == 0); assert (0); return 0; }