Do not detach when we think tracee is going to die.

Current code plays some ungodly tricks, trying to not detach
thread group leader until all threads exit.

Also, it detaches from a tracee when signal delivery is detected
which will cause tracee to exit.
This operation is racy (not to mention the determination
whether signal is set to SIG_DFL is a horrible hack):
after we determined that this signal is indeed fatal
but before we detach and let process die,
*other thread* may set a handler to this signal, and
we will leak the process, falsely displaying it as killed!

I need to look in the past to figure out why we even do it.
First guess is that it's a workaround for old kernel bugs:
kernel used to deliver exit notifications to the tracer,
not to real parent. These workarounds are ancient
(internal_exit is from 1995).

The patch deletes the hacks. We no longer need tcp->nclone_threads,
TCB_EXITING and TCB_GROUP_EXITING. We also lose a few rather
ugly functions.

I also added a new message: "+++ exited with EXITCODE +++"
which shows exact moment strace got exit notification.
It is analogous to existing "+++ killed by SIG +++" message.

* defs.h: Delete struct tcb::nclone_threads field,
  TCB_EXITING and TCB_GROUP_EXITING constants,
  declarations of sigishandled() and internal_exit().
* process.c (internal_exit): Delete this function.
  (handle_new_child): Don't ++tcp->nclone_threads.
* signal.c (parse_sigset_t): Delete this function.
  (sigishandled): Delete this function.
* strace.c (startup_attach): Don't tcbtab[tcbi]->nclone_threads++.
  (droptcb): Don't delay dropping if tcp->nclone_threads > 0,
  don't drop parent if its nclone_threads reached 0:
  just drop (only) this tcb unconditionally.
  (detach): don't drop parent.
  (handle_group_exit): Delete this function.
  (handle_ptrace_event): Instead of handle_group_exit, just drop tcb;
  do not panic if we see WIFEXITED from an attached pid;
  print "+++ exited with EXITCODE +++" for every WIFEXITED pid.
* syscall.c (internal_syscall):	Do not treat sys_exit specially -
  don't call internal_exit on it.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
5 files changed