From: Denys Vlasenko Date: Sat, 21 Mar 2015 16:51:52 +0000 (+0100) Subject: Show the syscall name in "resuming interrupted call" message X-Git-Tag: v4.11~561 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8497b6222ed8ef606996d0ceb2bae260d82f95e2;p=strace Show the syscall name in "resuming interrupted call" message When signal is received, or if we have attached to a process, current syscall (if process is in one) gets restarted. Some syscalls are restarted via "restart_syscall()" mechanism. On such sycalls, we don't show _which_ syscall gets restarted. IOW: users want to see "resuming interrupted nanosleep" instead of "resuming interrupted call" when they attach to "sleep 999". Kernel does expose this information. The only thing we need is to fetch syscall# on attach, and save it. This patch does this. It adds tcp->s_prev_ent, which is a pointer to struct_sysent of the previous syscall of this tracee. It can be NULL. sys_restart_syscall() is made to use it when the message is generated. To similarly handle restart_syscall() *after signals*, not just on attach, on each syscall exit patch saves exited syscall's data in the same member (tcp->s_prev_ent). Example: $ sleep 3 & strace -p $! Process 8728 attached restart_syscall(<... resuming interrupted nanosleep ...>) = 0 _exit(0) = ? +++ exited with 0 +++ Signed-off-by: Denys Vlasenko --- diff --git a/defs.h b/defs.h index dad4fe8b..9e269c7a 100644 --- a/defs.h +++ b/defs.h @@ -243,6 +243,7 @@ struct tcb { FILE *outf; /* Output file for this process */ const char *auxstr; /* Auxiliary info from syscall (see RVAL_STR) */ const struct_sysent *s_ent; /* sysent[scno] or dummy struct for bad scno */ + const struct_sysent *s_prev_ent; /* for "resuming interrupted SYSCALL" msg */ struct timeval stime; /* System time usage as of last process wait */ struct timeval dtime; /* Delta for system time usage */ struct timeval etime; /* Syscall entry time */ @@ -418,6 +419,7 @@ extern void call_summary(FILE *); extern void clear_regs(void); extern void get_regs(pid_t pid); +extern int get_scno(struct tcb *tcp); extern int umoven(struct tcb *, long, unsigned int, char *); #define umove(pid, addr, objp) \ diff --git a/signal.c b/signal.c index 867e1563..5ffd0d06 100644 --- a/signal.c +++ b/signal.c @@ -1056,8 +1056,13 @@ int sys_rt_sigtimedwait(struct tcb *tcp) int sys_restart_syscall(struct tcb *tcp) { - if (entering(tcp)) - tprints("<... resuming interrupted call ...>"); + if (entering(tcp)) { + tprintf("<... resuming interrupted %s ...>", + tcp->s_prev_ent + ? tcp->s_prev_ent->sys_name + : "system call" + ); + } return 0; } diff --git a/strace.c b/strace.c index b714255f..bf5531c5 100644 --- a/strace.c +++ b/strace.c @@ -2153,6 +2153,8 @@ trace(void) if (tcp->flags & TCB_STARTUP) { if (!startup_tcb(tcp)) return false; + if (get_scno(tcp) == 1) + tcp->s_prev_ent = tcp->s_ent; } sig = WSTOPSIG(status); diff --git a/syscall.c b/syscall.c index b37f43a6..33b22ecc 100644 --- a/syscall.c +++ b/syscall.c @@ -1127,7 +1127,7 @@ get_regs(pid_t pid) * other: error, trace_syscall_entering() should print error indicator * ("????" etc) and bail out. */ -static int +int get_scno(struct tcb *tcp) { long scno = 0; @@ -2239,6 +2239,7 @@ trace_syscall_exiting(struct tcb *tcp) } printing_tcp = tcp; + tcp->s_prev_ent = NULL; if (res != 1) { /* There was error in one of prior ptrace ops */ tprints(") "); @@ -2248,6 +2249,7 @@ trace_syscall_exiting(struct tcb *tcp) tcp->flags &= ~TCB_INSYSCALL; return res; } + tcp->s_prev_ent = tcp->s_ent; sys_res = 0; if (tcp->qual_flg & QUAL_RAW) {