[PATCH v3 2/3] The -z and -Z options print only successful and failing syscalls respectively. However, failure of syscall is only known after syscall return. Thus, we end up with something like this on, e.g., ENOENT:

Paul Chaignon paul.chaignon at gmail.com
Fri Jun 7 09:20:35 UTC 2019


There's still one case I'm not quite sure how to handle.  For example, for
one test case I wrote, I have the following output (a child thread execves
a sleeping leader):

  $ strace -f -eexit,execve,nanosleep ./status-exited >/dev/null
  execve("./status-exited", ["./status-exited"], 0x7fff54e81920 /* 65 vars */) = 0
  strace: Process 8831 attached
  [pid  8830] nanosleep({tv_sec=123, tv_nsec=0},  <unfinished ...>
  [pid  8831] nanosleep({tv_sec=0, tv_nsec=12345}, NULL) = 0
  [pid  8831] execve("./status-exited", ["./status-exited", "0"], NULL <unfinished ...>
  [pid  8830] <... nanosleep resumed> <unfinished ...>) = ?
  +++ superseded by execve in pid 8831 +++
  <... execve resumed>)                   = 0
  +++ exited with 0 +++

We won't know the status of the second execve call until it is resumed.
In the case of a shared log, we either have to decide whether we want to
print the unfinished execve call before knowing its status or we need to
print syscalls out of order.

I don't think the out-of-order solution is a good idea as it would be very
misleading to the user.  But I also don't know how to process unfinished
syscalls...

Paul

On Wed, Jun 05, 2019 at 10:21PM, Paul Chaignon wrote:
> On Wed, Jun 05, 2019 at 08:23:30PM +0300, Dmitry V. Levin wrote:
> > On Wed, Jun 05, 2019 at 11:33:22AM +0200, Paul Chaignon wrote:
> > > On Tue, Jun 04, 2019 at 12:31AM, Dmitry V. Levin wrote:
> > > > On Sun, Jun 02, 2019 at 10:42:01PM +0200, Paul Chaignon wrote:
> > > > > On Wed, May 22, 2019 at 12:13 PM Dmitry V. Levin <ldv at altlinux.org> wrote:
> > > > > >
> > > > > > On Mon, May 13, 2019 at 04:00:31PM +0000, Kohl, Burkhard wrote:
> > > > > > [...]
> > > > > > > > > diff --git a/strace.1.in b/strace.1.in index 76a74119..6ab95836 100644
> > > > > > > > > --- a/strace.1.in
> > > > > > > > > +++ b/strace.1.in
> > > > > > > > > @@ -771,6 +771,13 @@ Print unabbreviated versions of environment, stat, termios, etc.
> > > > > > > > >  calls.  These structures are very common in calls and so the default
> > > > > > > > > behavior displays a reasonable subset of structure members.  Use  this
> > > > > > > > > option to get all of the gory details.
> > > > > > > > > +.TP
> > > > > > > > > +.B \-z
> > > > > > > > > +Print successful syscalls only.
> > > > > > > >
> > > > > > > > It might be better to be precise here regarding what we mean by "successful" exactly.  Maybe "Print only
> > > > > > > > syscalls that did not return an error code"?
> > > > > > >
> > > > > > > Seems there are 3 possible outcomes for a syscall:
> > > > > > > - zero/successful
> > > > > > > - non-zero/not successful
> > > > > > > - void
> > > > > >
> > > > > > Strictly speaking, there are more than 3 possible outcomes for a syscall:
> > > > > > - syscall returns with an error
> > > > > > - syscall returns without an error
> > > > > > - syscall returns but strace fails to fetch error status (see e.g. <unavailable>)
> > > > > > - syscall does not return because of PTRACE_EVENT_EXIT (see print_event_exit)
> > > > > > - syscall does not return because of process disappearance (e.g. due to execve in a neighbour thread)
> > > > > 
> > > > > Wouldn't execve in a neightbour thread result in PTRACE_EVENT_EXIT? Are
> > > > > the exited and unfinished cases really different?
> > > > > 
> > > > > It looks like PTRACE_O_TRACEEXIT is set in all cases (both PTRACE_SEIZE
> > > > > and PTRACE_ATTACH), so when a neighbour thread does an execve, the tracee
> > > > > thread should be torn down and stopped with PTRACE_EVENT_EXIT before
> > > > > actual death. What am I missing?
> > > > 
> > > > Yes, your interpretation seems to be correct.  If I'm not mistaken,
> > > > we even rely on this behaviour in one of strace tests.
> > > > 
> > > > Nevertheless, I'm pretty sure processes can be killed in a way that would
> > > > look like disappearance.
> > > 
> > > I thought SIGKILL would be such a case.  The ptrace man page does mention
> > > PTRACE_EVENT_EXIT shouldn't happen in case of SIGKILL.  However, it also
> > > mentions that there's currently a bug:
> > > 
> > >   A SIGKILL signal may still cause a PTRACE_EVENT_EXIT stop before actual
> > >   signal death.  This may be changed in the future; SIGKILL is meant to
> > >   always immediately kill tasks even under ptrace.  Last confirmed on
> > >   Linux 3.13.
> > > 
> > > I was able to confirm the bug under Linux 5.1...
> > > 
> > > I also checked tests/threads-execve.c which tests different behaviors
> > > under execve.  All such behaviors seem to be covered by the exited status
> > > already.  Any other tests/functions(/signals?) I should look into that you
> > > think highlight the disappearance case?
> > 
> > I don't think we have a test that covers the case of disappearance without
> > PTRACE_EVENT_EXIT, but we have a piece of code that handles a very odd
> > situation: in printleader() " <unfinished ...>\n" is printed in case of
> > (printing_tcp->curcol != 0 && followfork >= 2 && printing_tcp == tcp).
> 
> Yes, that case is triggered by the threads-execve test for the sigsuspend
> and nanosleep syscalls.  The syscalls are then resumed
> (print_syscall_resume) on a PTRACE_EVENT_EXIT, so it's already covered by
> status=exit, at least for threads-execve's case.
> 
> > 
> > OK, lets introduce just one "unfinished" state for now as it makes little
> > sense to handle this elusive "unfinished without PTRACE_EVENT_EXIT"
> > condition differently.
> 
> Ok.
> 
> > 
> > 
> > -- 
> > ldv


More information about the Strace-devel mailing list