X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=strace.c;h=653009b5a3880c78b9b74983f264dd0cec1dd894;hb=215b7bb38dceadca466ea9f7cb53a9d3623668ad;hp=1b8b5cca312d94a543900e7ee24c6ea373717a7f;hpb=11abfb422a9dc2cd1d44500bad62464fe09b6fb0;p=strace diff --git a/strace.c b/strace.c index 1b8b5cca..653009b5 100644 --- a/strace.c +++ b/strace.c @@ -43,7 +43,9 @@ #ifdef HAVE_PRCTL # include #endif +#include +#include "scno.h" #include "ptrace.h" #include "printsiginfo.h" @@ -57,15 +59,7 @@ extern char *optarg; bool stack_trace_enabled = false; #endif -#if defined __NR_tkill -# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) -#else - /* kill() may choose arbitrarily the target task of the process group - while we later wait on a that specific TID. PID process waits become - TID task specific waits for a process under ptrace(2). */ -# warning "tkill(2) not available, risk of strace hangs!" -# define my_tkill(tid, sig) kill((tid), (sig)) -#endif +#define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) /* Glue for systems without a MMU that cannot provide fork() */ #if !defined(HAVE_FORK) @@ -192,6 +186,16 @@ strerror(int err_no) #endif /* HAVE_STERRROR */ +static void +print_version(void) +{ + printf("%s -- version %s\n" + "Copyright (C) %s The strace developers <%s>.\n" + "This is free software; see the source for copying conditions. There is NO\n" + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", + PACKAGE_NAME, PACKAGE_VERSION, "1991-2017", PACKAGE_URL); +} + static void usage(void) { @@ -386,24 +390,31 @@ ptrace_attach_or_seize(int pid) * Otherwise prints error message and returns -1. */ static int -ptrace_restart(int op, struct tcb *tcp, int sig) +ptrace_restart(const unsigned int op, struct tcb *const tcp, unsigned int sig) { int err; const char *msg; errno = 0; - ptrace(op, tcp->pid, (void *) 0, (long) sig); + ptrace(op, tcp->pid, 0L, (unsigned long) sig); err = errno; if (!err) return 0; - msg = "SYSCALL"; - if (op == PTRACE_CONT) - msg = "CONT"; - if (op == PTRACE_DETACH) - msg = "DETACH"; - if (op == PTRACE_LISTEN) - msg = "LISTEN"; + switch (op) { + case PTRACE_CONT: + msg = "CONT"; + break; + case PTRACE_DETACH: + msg = "DETACH"; + break; + case PTRACE_LISTEN: + msg = "LISTEN"; + break; + default: + msg = "SYSCALL"; + } + /* * Why curcol != 0? Otherwise sometimes we get this: * @@ -420,7 +431,7 @@ ptrace_restart(int op, struct tcb *tcp, int sig) if (err == ESRCH) return 0; errno = err; - perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig); + perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%u)", msg, tcp->pid, sig); return -1; } @@ -562,7 +573,7 @@ tprintf(const char *fmt, ...) va_start(args, fmt); if (current_tcp) { - int n = strace_vfprintf(current_tcp->outf, fmt, args); + int n = vfprintf(current_tcp->outf, fmt, args); if (n < 0) { if (current_tcp->outf != stderr) perror_msg("%s", outfname); @@ -1398,7 +1409,8 @@ startup_child(char **argv) } if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { kill_save_errno(pid, SIGKILL); - perror_msg_and_die("Unexpected wait status %x", status); + perror_msg_and_die("Unexpected wait status %#x", + status); } } /* Else: NOMMU case, we have no way to sync. @@ -1511,8 +1523,8 @@ test_ptrace_seize(void) if (WIFSIGNALED(status)) { return; } - error_msg_and_die("%s: unexpected wait status %x", - __func__, status); + error_msg_and_die("%s: unexpected wait status %#x", + __func__, status); } } #else /* !USE_SEIZE */ @@ -1659,7 +1671,7 @@ init(int argc, char *argv[]) qualify("abbrev=none"); break; case 'V': - printf("%s -- version %s\n", PACKAGE_NAME, VERSION); + print_version(); exit(0); break; case 'z': @@ -1769,8 +1781,14 @@ init(int argc, char *argv[]) } #ifdef USE_LIBUNWIND - if (stack_trace_enabled) + if (stack_trace_enabled) { + unsigned int tcbi; + unwind_init(); + for (tcbi = 0; tcbi < tcbtabsize; ++tcbi) { + unwind_tcb_init(tcbtab[tcbi]); + } + } #endif /* See if they want to run as another user. */ @@ -2043,7 +2061,7 @@ maybe_switch_tcbs(struct tcb *tcp, const int pid) struct tcb *execve_thread; long old_pid = 0; - if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0) + if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, &old_pid) < 0) return tcp; /* Avoid truncation in pid2tcb() param passing */ if (old_pid <= 0 || old_pid == pid) @@ -2398,7 +2416,7 @@ trace(void) * TODO: shouldn't we check for errno == EINVAL too? * We can get ESRCH instead, you know... */ - stopped = ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0; + stopped = ptrace(PTRACE_GETSIGINFO, pid, 0, &si) < 0; #if USE_SEIZE show_stopsig: #endif @@ -2434,7 +2452,8 @@ show_stopsig: * This should be syscall entry or exit. * Handle it. */ - if (trace_syscall(tcp) < 0) { + sig = 0; + if (trace_syscall(tcp, &sig) < 0) { /* * ptrace() failed in trace_syscall(). * Likely a result of process disappearing mid-flight. @@ -2448,6 +2467,7 @@ show_stopsig: */ return true; } + goto restart_tracee; restart_tracee_with_sig_0: sig = 0;