Re: utrace-ptrace detach with signal semantics

2009-10-11 Thread Roland McGrath
I'm replying out of order.  So I'm sorry I started rehashing some of this
same stuff in the other thread before reading where you'd already referred
to it.

 What if the tracee reports a signal and stops, the tracer detaches
 but does not wake it up because of SIGNAL_STOP_STOPPED ? In this
 case this signal will be visible after the next attach.
 
 OK, currently ptrace_detach() unconditionally wakes up the tracee.
 But we seem to agree this wakeup should be killed, it completely
 breaks the group-stop logic and it has other problems.

So today the manifest semantics in userland is that PTRACE_DETACH from a
signal stop causes immediate delivery of the signal in that thread
regardless of the group stoppedness.  In a (converted) job stop or
non-signal, non-syscall ptrace stop the tracee resumes and drops the passed
signr on the floor.  Those semantics are very clear for the single-threaded
case at least, so we can just be compatible.  

In MT cases where the result is a group-exit, that is pretty consistent
and reliable today, so we probably need to be compatible there too.  In
MT cases where the result is to flutter back into job stop (SIGSTOP et
al), then there too it is reliable today that you'll get another SIGCHLD
and wait wakeup to go with that freshly stopped again.

In MT cases where the result is to confuse the group-stop state, i.e.
tracee runs (signal handler or ignored signal) while group is supposedly
stopped, we probably don't break anything not already broken by cleaning
it up somehow.  But if the tracer does a loop of PTRACE_DETACH on each
tracee thread, then the result today is probably pretty consistent in
manifest behavior today: they all get back to running, even if the
SIGNAL_STOP_STOPPED flag is still set.  But I'm not at all sure anything
could discern from userland that SIGNAL_STOP_STOPPED is still set.  It
will be set anew or cleared by the time it actually matters.  So maybe
it really is consistent enough with today's observable behavior just to
have PTRACE_DETACH clear SIGNAL_STOP_STOPPED.  I'm guessing that will be
pretty well consistent in the loop-of-detach case (by the end of it).
I'm not really sure what would go different in an oddball case where you
PTRACE_DETACH'd one thread but the others were actually left stopped
(e.g. in true job stop and you only ever attached the one thread).  But
it probably doesn't much matter, that usage mode must already be pretty
broken I would think.

 If monitor really wants to kill the tracee it should use SIGKILL ;)

Say it wants a core dump.

 Any other fatal signal can be ignored by the tracee's sub-thread after
 detach but before the tracee returns from ptrace_signal().

Say they never tested the MT case before and haven't started caring
about it now.  They just want what they have observed before to stay the
same as they saw with the old kernel.

 Since detach_signal() actually sends the signal, ptrace(DETACH, SIGKILL)
 really works: it wakes up SIGNAL_STOP_STOPPED tracee.

Today's manifest behavior (via the bogus wake_up_process) is that this
SIGKILL will get through and take effect (in signal stops, as above).
So that should stay.  

As to the theory of things, this is the flip side of the whole
SIGNAL_STOP_DEQUEUED issue I just posted about earlier.  Whereas only an
earlier SIGCONT/SIGKILL would have cleared stop signals and thus should
clear any pending-equivalent half-delivered stop signals, earlier
stop signals would have cleared a pending SIGCONT.  I'm not entirely
sure what should happen in all the SIGCONT cases, but we can probably
enumerate them and hash those out.  I doubt anybody is depending much on
the corners of that.

For the SIGKILL cases, it's more clear.  No matter what, if a SIGKILL
doesn't just get dropped on the floor (non-signal stop cases), then it's
going to override everything else and soon.

 Lets discuss how we can implement detach to be compatible...
 We already discussed detached_ops. So, we either change engine-ops
 (my choice) or add the new engine with -ops = detached_ops and detach
 the ptrace engine. 

I don't recall all of the earlier discussion about this in detail.
But yes, they are equivalent and I think a fresh engine is cleaner.

 We need detached_report_signal() callback which
 fixups siginfo if signr != info-si_signo and returns
 UTRACE_DETACH | UTRACE_SIGNAL_DELIVER.

Right, ptrace_report_signal does that now with -resume = UTRACE_DETACH.

 How can detached_report_signal() set info-si_pid correctly? the
 tracer has gone away. This probably means this info should be prepared
 during detach, the tracer should fill context-siginfo.

It means that if the tracer cared at all, he did PTRACE_SETSIGINFO so
this would be moot.  The vanilla kernel today uses si_pid and si_uid
values of what's either the new tracer (with racing PTRACE_ATTACH) or
the real parent at the time of actual resumption.  It can be any of
those values or 0 and I think it's fine.

 But the real problem, I can't see how can we teach 

Re: utrace-ptrace detach with signal semantics

2009-10-11 Thread Roland McGrath
 I think always-reply-to-all is the best policy ;)

For some people's mail-handling habits it makes a difference, so it is
always safest not to trim individuals.  For me personally, I always
see the list copies just the same as the ones CC'd to me personally,
so I don't care to be in the CC list as long as the mailing list is
CC'd (and I prefer shorter CC lists for no special reason).


Thanks,
Roland



Re: utrace-ptrace detach with signal semantics

2009-10-10 Thread Jan Kratochvil
On Sat, 10 Oct 2009 18:24:21 +0200, Oleg Nesterov wrote:
 On 10/06, Jan Kratochvil wrote:
 
  Yes, I agree with the current general behavior of ptrace there is missing:
 if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)
 
  [...snip...]
 
  --- attach-into-signal.c31 Jan 2009 21:11:40 -  1.5
  +++ attach-into-signal.c6 Oct 2009 14:27:08 -
  @@ -224,6 +224,18 @@ static void reproduce (void)
 child = 0;
 return;
   }
  +  /* SIGPIPE was still pending and it has not been yet delivered.  */
  +  if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)
  +{
  +  /* Deliver it and get the queued SIGSTOP.  */
  +  errno = 0;
  +  ptrace (PTRACE_CONT, child, (void *) 1, (void *) SIGPIPE);
  +  assert_perror (errno);
  +
  +  errno = 0;
  +  pid = waitpid (child, status, 0);
  +  assert (pid == child);
  +}
 assert (WIFSTOPPED (status));
 assert (WSTOPSIG (status) == SIGSTOP);
 /* let tracee run. it must be killed very soon by SIGPIPE */
 
 Jan, please revert this change.

Reverted (VERBOSE-caught with FAIL now).


Jan



Re: utrace-ptrace detach with signal semantics

2009-10-10 Thread Oleg Nesterov
On 10/10, Jan Kratochvil wrote:

 On Sat, 10 Oct 2009 18:24:21 +0200, Oleg Nesterov wrote:
  On 10/06, Jan Kratochvil wrote:
  
   Yes, I agree with the current general behavior of ptrace there is missing:
  if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)
  
   [...snip...]
  
   --- attach-into-signal.c  31 Jan 2009 21:11:40 -  1.5
   +++ attach-into-signal.c  6 Oct 2009 14:27:08 -
   @@ -224,6 +224,18 @@ static void reproduce (void)
  child = 0;
  return;
}
   +  /* SIGPIPE was still pending and it has not been yet delivered.  */
   +  if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)
   +{
   +  /* Deliver it and get the queued SIGSTOP.  */
   +  errno = 0;
   +  ptrace (PTRACE_CONT, child, (void *) 1, (void *) SIGPIPE);
   +  assert_perror (errno);
   +
   +  errno = 0;
   +  pid = waitpid (child, status, 0);
   +  assert (pid == child);
   +}
  assert (WIFSTOPPED (status));
  assert (WSTOPSIG (status) == SIGSTOP);
  /* let tracee run. it must be killed very soon by SIGPIPE */
  
  Jan, please revert this change.
 
 Reverted

Thanks!

 (VERBOSE-caught with FAIL now).

Cough. please translate this to me ;)

Oleg.



Re: utrace-ptrace detach with signal semantics

2009-10-10 Thread Jan Kratochvil
On Sat, 10 Oct 2009 18:48:29 +0200, Oleg Nesterov wrote:
 On 10/10, Jan Kratochvil wrote:
  (VERBOSE-caught with FAIL now).
 
 Cough. please translate this to me ;)

(Cc of each such mail to Roland does not look OK to me but removing Ccs is
also not OK)


--- tests/attach-into-signal.c  6 Oct 2009 19:21:35 -   1.6
+++ tests/attach-into-signal.c  10 Oct 2009 16:47:46 -  1.7
@@ -227,14 +227,8 @@ static void reproduce (void)
   /* SIGPIPE was still pending and it has not been yet delivered.  */
   if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)
 {
-  /* Deliver it and get the queued SIGSTOP.  */
-  errno = 0;
-  ptrace (PTRACE_CONT, child, (void *) 1, (void *) SIGPIPE);
-  assert_perror (errno);
-
-  errno = 0;
-  pid = waitpid (child, status, 0);
-  assert (pid == child);
+  VERBOSE (Forbidden to catch pending signal from PTRACE_DETACH);
+  exit (1);
 }
   assert (WIFSTOPPED (status));
   assert (WSTOPSIG (status) == SIGSTOP);



Re: utrace-ptrace detach with signal semantics

2009-10-07 Thread Jan Kratochvil
On Wed, 07 Oct 2009 15:33:49 +0200, Oleg Nesterov wrote:
 On 10/06, Jan Kratochvil wrote:
  It should work also for PTRACE_SINGLESTEP.
 
 Heh. Yes, but with one exception.
 
   - the tracee has a hanlder for, say, SIGHUP
 
   - the tracee deques SIGHUP, reports to the tracer,
 and stops.
 
   - the tracer does ptrace(SINGLESTEP, SIGHUP)
 
 // it could use another signr, this works.
 // but the tracer must have a handler or
 // everething is OK.
 
   - the tracee delivers SIGHUP to itself, handle_signal()
 notices TIF_SINGLESTEP and calls ptrace_notify().
 
 Now, the tracee reports SIGTRAP, but the next time the tracer does
 ptrace(WHATEVER, SIGNR) SIGNR will be ignored.

OK, this is really a border case I did not mean.

In such case the SIGHUP handler still is not fully execting and as the
non-realtime signals do not nest (count) it is OK it gets activated only once.


I did mean some more normal case of:

ptrace (PTRACE_SIGNALSTEP, 0) = 0
waitpid() = SIGTRAP
ptrace (PTRACE_SIGNALSTEP, 0) = 0
waitpid() = SIGTRAP
PTRACE (PTRACE_DETACH, SIGSTOP) = 0

which I assume it will work.


Thanks,
Jan



Re: utrace-ptrace detach with signal semantics

2009-10-07 Thread Oleg Nesterov
On 10/07, Jan Kratochvil wrote:

 OK, this is really a border case I did not mean.

 In such case the SIGHUP handler still is not fully execting and as the
 non-realtime signals do not nest (count) it is OK it gets activated only once.


 I did mean some more normal case of:

 ptrace (PTRACE_SIGNALSTEP, 0) = 0
 waitpid() = SIGTRAP
 ptrace (PTRACE_SIGNALSTEP, 0) = 0
 waitpid() = SIGTRAP
 PTRACE (PTRACE_DETACH, SIGSTOP) = 0

 which I assume it will work.

Yes, this should work. In this case the tracee really has the
pending SIGTRAP which will be dequeued and reported.

ptrace(WHATEVER, SIGNR) will change si_signo (or cancel the
signal if SIGNR = 0), PTRACE_SETSIGINFO works too.

Oleg.



Re: utrace-ptrace detach with signal semantics

2009-10-07 Thread Roland McGrath
 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.

Correct.

 Why? Should utrace-ptrace be 100% compatible here?

I think it should, yes.  There is a rationale for it that makes sense to
me, and it is most certainly consistent, observable behavior on which
existing applications could very well depend subtly, so regardless of
right I think this one is well within 100% bug-compatibility territory.

The rationale I see is that the debugger observed the signal, decided it
wanted the tracee to experience the normal effects of the signal and be
done with it after that.  If it's a termination signal, the debugger really
expects that the tracee can do nothing but die.  (Given the tortured
historic logic of the ptrace code paths, this applies only to signal stops
and only when it either passes back the same signal number or at least
another one that is not blocked.)  Now replace debugger with monitor or
(dismal) security-checking syscall tracing product, or just shudder while
trying not to imagine what all inane things ptrace might already be in use
for.  It could be important to someone out there e.g. that some other
process of the tracee's UID cannot race in there and rescue it from dying.

 I do not think there is a real life application that does
 ATTACH + DETACH and relies on fact it must not see this sig.

We can hope, but we cannot assume.  There are always better ways to achieve
the same true ends than the corner case examples like the one I gave, but
that doesn't mean people haven't written the stupid ones in applications
already shipped long ago and never to be rethought again (until we get the
blame for breaking them in the new kernel).


Thanks,
Roland



Re: utrace-ptrace detach with signal semantics

2009-10-07 Thread Roland McGrath
  Naive programs expect the first signal after PTRACE_ATTACH will be SIGSTOP.
 
 They should not, this is just wrong.
 
 And I think the proposed change doesn't change the behaviour
 in this sense.

It does not in the general sense.  But it does change the behavior of
certain 100% predictable patterns that could have been used before.


Thanks,
Roland



Re: utrace-ptrace detach with signal semantics

2009-10-07 Thread Roland McGrath
 OK. Let's see what Roland thinks.

I think the whole stoppedness vs detach et al discussion is a separate
issue from the basic PTRACE_DETACH,signr behavior, and I think I want to
discuss that in the other thread we have whose subject says it's about
that.  I think I've covered the (separate) basic parting-signal issue now.

 Hmm. I guess with utrace it will be simple to do this change...

You're supposed to say that before every patch!  Didn't you get the memo? ;-)


Thanks,
Roland



Re: utrace-ptrace detach with signal semantics

2009-10-07 Thread Roland McGrath
 In which specific cases SIGNR can get ignored?

There are two fundamental kinds of ptrace stops: real signal stops, and
fake (or ptrace_notify()) stops.  In the latter, you are not in the
right place in the kernel for direct signal delivery, so it never works
fully normally.  All the optional event stops are in this latter category,
i.e. everything not for a signal.  

The syscall entry and exit stops have an explicit queuing behavior
(i.e. it's about the same as if you'd just called tgkill before
PTRACE_CONT--any PTRACE_SETSIGINFO you've done has no effect on this new
signal, but you will see it in a real signal stop soon when it's dequeued).
The others do not have any such kludge, so they just drop the signr
argument on the floor.  

Note that the default exec stop really is a signal (a plain SIGTRAP sent as
if by raise(SIGTRAP); right after exec), but PTRACE_EVENT_EXEC is not.

Some of the PTRACE_SINGLESTEP cases on some architectures use fake stops.
When stepping over an average user instruction, it's always a real SIGTRAP.
But e.g., stepping the syscall insn on powerpc and some others (perhaps all
but x86) is not.  As Oleg mentioned, when PTRACE_SINGLESTEP,signr stops
immediately after handler setup, that is also a fake stop.  These cases are
something that we probably can and should fix and arch-harmonize upstream
so that PTRACE_SINGLESTEP consistently produces a real SIGTRAP signal stop
after which the full range of

I don't think the behavior for the special event stops will change.


Thanks,
Roland



Re: utrace-ptrace detach with signal semantics

2009-10-07 Thread Roland McGrath
 after which the full range of
[oops, left that thought unfinished!]
... signal control options works (immediate delivery, SETSIGIFNO obeyed)



Re: utrace-ptrace detach with signal semantics

2009-10-06 Thread Oleg Nesterov
On 10/06, Jan Kratochvil wrote:

 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.

Confused. Do you mean we should fix the kernel to match this
expectation?

This was never true. PTRACE_ATTACH sends SIGSTOP to the tracee,
but this SIGSTOP is not magical, there is no any guarantee it
will be dequeued before other pending signals.

You attached the test-case which sends SIGALRM to itself in a loop.
If the tracer attaches to this program, it is very possible that
SIGALRM will be reported, not SIGSTOP.

But! this has nothing to do with the question I asked ;) see below.

  And I think the proposed change doesn't change the behaviour
  in this sense.

 We started to discuss two different changes:

We started to discuss 3 different things, not 2. Please see below,
my question was quite different.

 my asked for one: ptrace(DETACH, SIGSTOP) should leave the tracee stopped.

Yes,

 a new one: First signal after PTRACE_ATTACH should be SIGSTOP.

This was never true, afaics. Of course, if nobody sends other signals
to the tracee then SIGSTOP will be the first signal, but only because
there are no other signals which could be dequeued/reported.

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?

It fails on ptrace-over-utrace. And I can't understand why this
behaviour is important. I hope it is not.

Once again. Suppose that the tracer does ptrace(PTRACE_DETACH, SIGXXX).
Currently, if the next thacer attaches right after this detach it has no
way to intercept SIGXXX, it will be never reported via ptrace_signal().

Is this really important? Do you know any application which can be
broken if we change this behaviour? With the current utrace-ptrace
implementation SIGXXX can be reported to the new tracer.

OK, this relates to the first signal should be SIGSTOP but this
is wrong anyway, and the case above is very unlikely.

Oleg.



Re: utrace-ptrace detach with signal semantics

2009-10-06 Thread Jan Kratochvil
On Tue, 06 Oct 2009 15:10:10 +0200, Oleg Nesterov wrote:
 On 10/06, Jan Kratochvil wrote:
  On Mon, 05 Oct 2009 21:00:37 +0200, Oleg Nesterov wrote:
   On 10/05, Jan Kratochvil wrote:
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.
 
 Confused. Do you mean we should fix the kernel to match this
 expectation?

Yes, I was thinking it would be a good idea.

 This was never true.

I agree.

 You attached the test-case which sends SIGALRM to itself in a loop.
 If the tracer attaches to this program, it is very possible that
 SIGALRM will be reported, not SIGSTOP.

Yes.  And the real world tracers do not expect so.


   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.

Second keyword PTRACE_ATTACH is on line 167.
First keyword SIGPIPE is on line 199.
Line 167 cannot see anything from line 199.

Assuming you did mean third PTRACE_ATTACH.

Line 222:  if (WIFSIGNALED (status)  WTERMSIG (status) == SIGPIPE)
Line 227:  assert (WIFSTOPPED (status));
Line 228:  assert (WSTOPSIG (status) == SIGSTOP);

Yes, I agree with the current general behavior of ptrace there is missing:
   if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)


 It fails on ptrace-over-utrace.

Attached, I do not have kernel.rpm with ptrace-over-utrace ready, please
verify it and check it in (or ping me or so).


 Once again. Suppose that the tracer does ptrace(PTRACE_DETACH, SIGXXX).
 Currently, if the next thacer attaches right after this detach it has no
 way to intercept SIGXXX, it will be never reported via ptrace_signal().

No matter if it gets reported to the new tracer still SIGXXX should never get
lost.  If it is not reported to the new tracer then it will be always
processed by the tracee, is it right?


 Is this really important? Do you know any application which can be
 broken if we change this behaviour? With the current utrace-ptrace
 implementation SIGXXX can be reported to the new tracer.

I think there is no application which would handle non-SIGSTOP as the first
signal after PTRACE_ATTACH while it would get confused by getting non-SIGSTOP
signal as the first one after PTRACE_ATTACH after PTRACE_DETACH.


 OK, this relates to the first signal should be SIGSTOP but this
 is wrong anyway, and the case above is very unlikely.

If the first signal should be SIGSTOP is not satisfied (current state)
I think you can freely change this behavior whether SIGXXX will be reported to
the new tracer and we should apply the attached ptrace-testsuite patch.

If the first signal should be SIGSTOP gets fixed/satisfied (proposed state)
I think it is clear SIGXXX from PTRACE_DETACH must not be lost and it must not
be visible as the first signal after PTRACE_ATTACH.  In such case the
ptrace-testsuite testcase attach-into-signal should be simplified a lot to
always just require SIGSTOP as the first signal after PTRACE_ATTACH and the
attached change gets irrelevant in such case.


Thanks,
Jan
--- attach-into-signal.c31 Jan 2009 21:11:40 -  1.5
+++ attach-into-signal.c6 Oct 2009 14:27:08 -
@@ -224,6 +224,18 @@ static void reproduce (void)
   child = 0;
   return;
 }
+  /* SIGPIPE was still pending and it has not been yet delivered.  */
+  if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)
+{
+  /* Deliver it and get the queued SIGSTOP.  */
+  errno = 0;
+  ptrace (PTRACE_CONT, child, (void *) 1, (void *) SIGPIPE);
+  assert_perror (errno);
+
+  errno = 0;
+  pid = waitpid (child, status, 0);
+  assert (pid == child);
+}
   assert (WIFSTOPPED (status));
   assert (WSTOPSIG (status) == SIGSTOP);
   /* let tracee run. it must be killed very soon by SIGPIPE */


Re: utrace-ptrace detach with signal semantics

2009-10-06 Thread Jan Kratochvil
On Tue, 06 Oct 2009 19:14:28 +0200, Oleg Nesterov wrote:
 On 10/06, Jan Kratochvil wrote:
[...]
  If it is not reported to the new tracer then it will be always
  processed by the tracee, is it right?
 
 Yes, sure.
 
 (But, just in case... if the tracer does ptrace(DETACH, SIGNR), this
  signr only matters if the tracee was stopped after reporting syscall
  or signal, otherwise SIGNR is ignored).

In which specific cases SIGNR can get ignored?

Whole PTRACE_DETACH will be ignored if the tracee is not stopped.
It SIGNR will be proabably ignored if the tracee is now dead.
Otherwise SIGNR should get delivered, shouldn't it?


  +  /* SIGPIPE was still pending and it has not been yet delivered.  */
  +  if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)
[...]
 Yes, I didn't verify this yet, but I think with this patch the
 test-case should succeed with utrace-ptrace kernel.

Checked-in.


Thanks,
Jan



Re: utrace-ptrace detach with signal semantics

2009-10-06 Thread Oleg Nesterov
On 10/06, Jan Kratochvil wrote:

 On Tue, 06 Oct 2009 19:14:28 +0200, Oleg Nesterov wrote:
  On 10/06, Jan Kratochvil wrote:
 [...]
   If it is not reported to the new tracer then it will be always
   processed by the tracee, is it right?
  
  Yes, sure.
  
  (But, just in case... if the tracer does ptrace(DETACH, SIGNR), this
   signr only matters if the tracee was stopped after reporting syscall
   or signal, otherwise SIGNR is ignored).
 
 In which specific cases SIGNR can get ignored?
 
 Whole PTRACE_DETACH will be ignored if the tracee is not stopped.
 It SIGNR will be proabably ignored if the tracee is now dead.
 Otherwise SIGNR should get delivered, shouldn't it?

No (afaics).

For example, the tracee reports PTRACE_EVENT_EXEC and stops. In this
case SIGNR has no effect after PTRACE_CONT/DETACH/etc.

SIGNR does not ignored after the tracee reported syscall entry/exit or
signal.

If you think this should be changed, please tell. As always, I do not
know if it was supposed or not. (and in fact I should re-check my
understanding after sleep).

   +  /* SIGPIPE was still pending and it has not been yet delivered.  */
   +  if (WIFSTOPPED (status)  WSTOPSIG (status) == SIGPIPE)
 [...]
  Yes, I didn't verify this yet, but I think with this patch the
  test-case should succeed with utrace-ptrace kernel.

 Checked-in.

Thanks!

Oleg.



Re: utrace-ptrace detach with signal semantics

2009-10-06 Thread Jan Kratochvil
On Tue, 06 Oct 2009 22:05:16 +0200, Oleg Nesterov wrote:
 For example, the tracee reports PTRACE_EVENT_EXEC and stops. In this
 case SIGNR has no effect after PTRACE_CONT/DETACH/etc.
 
 SIGNR does not ignored after the tracee reported syscall entry/exit or
 signal.

OK, if only such exceptional cases as PTRACE_EVENT_EXEC that should not matter
I think.  It should work also for PTRACE_SINGLESTEP.


Thanks,
Jan



Re: utrace-ptrace detach with signal semantics

2009-10-05 Thread Oleg Nesterov
On 10/05, Oleg Nesterov wrote:

 On 10/05, Jan Kratochvil wrote:
 
  On Mon, 05 Oct 2009 04:51:32 +0200, Oleg Nesterov wrote:

   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.

Just in case... If I change the test-case

--- a/ptrace-tests/tests/attach-into-signal.c   2009-01-31 
13:11:40.0 -0800
+++ b/ptrace-tests/tests/attach-into-signal.c   2009-09-20 
13:32:30.0 -0700
@@ -225,9 +225,9 @@ static void reproduce (void)
   return;
 }
   assert (WIFSTOPPED (status));
-  assert (WSTOPSIG (status) == SIGSTOP);
+  assert (WSTOPSIG (status) == SIGPIPE);
   /* let tracee run. it must be killed very soon by SIGPIPE */
-  ptrace (PTRACE_CONT, child, (void *) 1, (void *) 0);
+  ptrace (PTRACE_CONT, child, (void *) 1, (void *) SIGPIPE);
   assert_perror (errno);
   pid = waitpid (child, status, 0);
   assert (pid == child);

then it doesn't fail.

 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.

So... Jan, do you think this behaviour change can break gdb?

Oleg.



utrace-ptrace detach with signal semantics

2009-10-04 Thread Oleg Nesterov
Jan, Roland, I have the question.

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? Should utrace-ptrace be 100% compatible here?

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.

Could you explain what can be breaked if SIGXXX will be reported
to the next tracer (assuming the 2nd ATTACH is fast enough) ?

I do not think there is a real life application that does
ATTACH + DETACH and relies on fact it must not see this sig.

Oleg.