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 <unfinished ...>
After: 10533 sendto(-1, 0x804895e, 17, 0, NULL, 0 <ptrace(SYSCALL):No such process>
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 "<unfinished ...>"
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 <vda.linux@googlemail.com>
diff --git a/defs.h b/defs.h
index 7179c32..c87b97d 100644
--- a/defs.h
+++ b/defs.h
@@ -316,7 +316,6 @@
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 04efd1e..ad29bb4 100644
--- a/strace.c
+++ b/strace.c
@@ -352,10 +352,9 @@
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 @@
if (op == PTRACE_LISTEN)
msg = "LISTEN";
#endif
+ /*
+ * Why curcol != 0? Otherwise sometimes we get this:
+ *
+ * 10252 kill(10253, SIGKILL) = 0
+ * <ptrace(SYSCALL,10252):No such process>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(" <ptrace(%s):%s>\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 @@
if (printing_tcp) {
outf = printing_tcp->outf;
curcol = printing_tcp->curcol;
- if (printing_tcp->ptrace_errno) {
- if (printing_tcp->flags & TCB_INSYSCALL) {
- tprints(" <unavailable>) ");
- tabto();
- }
- tprints("= ? <unavailable>\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 @@
* (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 @@
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;
}