From: Denys V. <dvl...@re...> - 2009-04-23 14:11:47
|
Interrupting strace with ^C works in practice, but from code inspection I see some scenarios when we may leave some tracees stopped when strace exits. This patch catches these cases by not allowing ^C exit to commence until all collected tracees are dealt with. Changelog: * strace.c (collect_stopped_tcbs): Expose remembered_pid static variable. (trace): Do not exit yet if ^C pressed but remembered_pid is nonzero. It needs to be handled first. (handle_stopped_tcbs): Remove ^C test, we must not exit until we processed _all_ collected tasks. -- vda --- strace.c 20 Apr 2009 18:20:18 -0000 1.115 +++ strace.c 23 Apr 2009 13:36:58 -0000 @@ -2249,13 +2249,14 @@ } #endif +#ifdef LINUX +static int remembered_pid; +static int remembered_status; +#endif + static struct tcb * collect_stopped_tcbs(void) { -#ifdef LINUX - static int remembered_pid; - static int remembered_status; -#endif int pid; int wait_errno; int status; @@ -2718,9 +2719,6 @@ tcp->flags &= ~TCB_SUSPENDED; continue; } - /* we handled the STATUS, we are permitted to interrupt now. */ - if (interrupted) - return 0; if (trace_syscall(tcp) < 0) { /* trace_syscall printed incompletely decoded syscall, * add error indicator. @@ -2793,8 +2791,13 @@ * To fix it, we collect *all* waitable tasks, then handle * them all, then repeat. */ - if (interrupted) + /* If remembered_pid exists, there is one extra tracee + * "collected" earlier. Do not exit in this case, we need + * to handle it first. + */ + if (remembered_pid == 0 && interrupted) { return 0; + } tcbs = collect_stopped_tcbs(); if (!tcbs) break; |
From: Mike F. <va...@ge...> - 2009-04-27 07:06:36
|
On Thursday 23 April 2009 09:45:15 Denys Vlasenko wrote: > Interrupting strace with ^C works in practice, > but from code inspection I see some scenarios > when we may leave some tracees stopped when > strace exits. fwiw, ive seen this in practice ... after killing strace, the children are left hanging around -mike |