From: Denys Vlasenko Date: Wed, 21 Mar 2012 09:32:49 +0000 (+0100) Subject: Report some ptrace failures; nuke tcp->ptrace_errno X-Git-Tag: v4.7~48 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=235067525cc064a9a466c245fa8a6265ae136306;p=strace Report some ptrace failures; nuke tcp->ptrace_errno Report some (not all) ptrace errors, namely, errors on ptrace restart operations. Before: 10533 sendto(-1, 0x804895e, 17, 0, NULL, 0 After: 10533 sendto(-1, 0x804895e, 17, 0, NULL, 0 This tells user that strace failed to let sendto syscall to be entered - process was dead at that point of time. It is (marginally) better than to always say "" While at it, patch removes tcp->ptrace_errno. I added it many months ago, and it looks that after all it is not needed for ptrace error detection: I failed to execute a single existing code path which is accessible through that variable only. * defs.h: Remove struct tcp::ptrace_errno field. * strace.c (ptrace_restart): Emit message to log on error. (printleader): Remove "if (printing_tcp->ptrace_errno)..." code. (trace): Remove !tcp->ptrace_errno check, it's always true. Signed-off-by: Denys Vlasenko --- diff --git a/defs.h b/defs.h index 7179c320..c87b97df 100644 --- a/defs.h +++ b/defs.h @@ -316,7 +316,6 @@ struct tcb { long long ext_arg[MAX_ARGS]; /* System call arguments */ #endif long u_rval; /* (first) return value */ - int ptrace_errno; #if SUPPORTED_PERSONALITIES > 1 int currpers; /* Personality at the time of scno update */ #endif diff --git a/strace.c b/strace.c index 04efd1e6..ad29bb40 100644 --- a/strace.c +++ b/strace.c @@ -352,10 +352,9 @@ ptrace_restart(int op, struct tcb *tcp, int sig) errno = 0; ptrace(op, tcp->pid, (void *) 0, (long) sig); err = errno; - if (!err || err == ESRCH) + if (!err) return 0; - tcp->ptrace_errno = err; msg = "SYSCALL"; if (op == PTRACE_CONT) msg = "CONT"; @@ -365,6 +364,22 @@ ptrace_restart(int op, struct tcb *tcp, int sig) if (op == PTRACE_LISTEN) msg = "LISTEN"; #endif + /* + * Why curcol != 0? Otherwise sometimes we get this: + * + * 10252 kill(10253, SIGKILL) = 0 + * 10253 ...next decode... + * + * 10252 died after we retrieved syscall exit data, + * but before we tried to restart it. Log looks ugly. + */ + if (curcol != 0) { + tprintf(" \n", msg, strerror(err)); + line_ended(); + } + if (err == ESRCH) + return 0; + errno = err; perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig); return -1; } @@ -537,15 +552,6 @@ printleader(struct tcb *tcp) if (printing_tcp) { outf = printing_tcp->outf; curcol = printing_tcp->curcol; - if (printing_tcp->ptrace_errno) { - if (printing_tcp->flags & TCB_INSYSCALL) { - tprints(" ) "); - tabto(); - } - tprints("= ? \n"); - printing_tcp->ptrace_errno = 0; - printing_tcp->curcol = 0; - } if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) { /* * case 1: we have a shared log (i.e. not -ff), and last line @@ -2164,10 +2170,10 @@ trace(void) * (Or it still can be that pesky post-execve SIGTRAP!) * Handle it. */ - if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { - /* ptrace() failed in trace_syscall() with ESRCH. + if (trace_syscall(tcp) < 0) { + /* ptrace() failed in trace_syscall(). * Likely a result of process disappearing mid-flight. - * Observed case: exit_group() terminating + * Observed case: exit_group() or SIGKILL terminating * all processes in thread group. * We assume that ptrace error was caused by process death. * We used to detach(tcp) here, but since we no longer @@ -2182,11 +2188,12 @@ trace(void) sig = 0; restart_tracee: /* Remember current print column before continuing. */ - tcp->curcol = curcol; if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { + tcp->curcol = curcol; cleanup(); return -1; } + tcp->curcol = curcol; } return 0; }