]> granicus.if.org Git - strace/commit
strace: expand -D option
authorFanda Uchytil <strace.t8xuewpmde@h4x.cz>
Sat, 5 Oct 2019 22:55:13 +0000 (00:55 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 7 Oct 2019 11:33:37 +0000 (11:33 +0000)
commit1f58235b13a3e6dda0bbff9b66ac583a71b69583
treea089a226d85a2fff8f2f53e5ca6f232b81863d01
parente9cb6ff5e2ed187c77259c86a8094e00d1eddc2d
strace: expand -D option

As of now, despite of being stated that -D option runs strace as a "detached"
grandchild (and the option name being named after "daemon"), strace
still runs in the same process group and session, thus not being
"detached" in a common sense and being subjected to process group kill
and session termination kill. Quoting[1]:

    I stumble upon unexpected behavior: if strace is used with option '-D'
    (tracer as a detached grandchild) and process (leader) kills whole
    process group, it will kill strace too.

    It can be easily reproduced by `timeout` from "coreutils":

      # timeout -s KILL 2 strace -D -o ./strace-inside.log /bin/sleep 10 &

    Here we can see, that `strace` didn't finished its output (because it
    was killed):

      # tail -n 1 ./strace-inside.log
      nanosleep({tv_sec=10, tv_nsec=0},

    If `timeout` is not run in '--foreground' mode, it changes process group
    and after "timeout" it sends two kills:

      setpgid(0, 0)                           = 0
      kill(37337, SIGKILL)                    = 0
      kill(0, SIGKILL)                        = ?

    The first kill is for the `sleep` and the second one is for the process
    group (which is `strace` part of). PIDs and their relations are:

      timeout  pid=30595   [ppid=476   bash   ]     pgrp=30595
      sleep    pid=37337   [ppid=30595 timeout]     pgrp=30595
      strace   pid=30603   [ppid=1     systemd]     pgrp=30595

    Here is "strace log" of `strace` inside `timeout`:

      strace: Process 30603 attached
      wait4(-1,  <unfinished ...>)            = ?
      +++ killed by SIGKILL +++

    I think that detached `strace` should not be killed like that -- it
    should not be part of former grandparents' "job pipeline".

While this behaviour is not exactly intuitive, it is implemented this
way for quite some time, so it might be relied upon by some of strace
users.  In order to address this issue, two new levels of
"daemonisation" are added, that put strace in a separate process group
and session, respectively.

[1] https://lists.strace.io/pipermail/strace-devel/2019-October/009160.html

* strace.1.in (.SH SYNOPSIS): Update.
(.SS Tracing): Document -DD and -DDD.
* strace.c (DAEMONIZE_NONE, DAEMONIZE_GRANDCHILD, DAEMONIZE_NEW_PGROUP,
* DAEMONIZE_NEW_SESSION, DAEMONIZE_OPTS_GUARD__, MAX_DAEMONIZE_OPTS):
* New enumeration entities.
(daemonized_tracer): Change type to unsigned int.
(usage): Document -DD and -DDD.
(startup_attach) <daemonized_tracer == DAEMONIZE_NEW_PGROUP>: Call
setpgid.
<daemonized_tracer == DAEMONIZE_NEW_SESSION>: Call setsid.
(init) <case 'D'>: Increase daemonized_tracer instead of setting to 1.
(init): Bail out if too many -D's are given.
* NEWS: Mention this improvement.
* tests/options-syntax.test: Add checks for -D option usage.

Co-authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
NEWS
strace.1.in
strace.c
tests/options-syntax.test