]> granicus.if.org Git - strace/blobdiff - strace.c
sg_io: cleanup printing of sg_io buffers
[strace] / strace.c
index 1b8b5cca312d94a543900e7ee24c6ea373717a7f..653009b5a3880c78b9b74983f264dd0cec1dd894 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -43,7 +43,9 @@
 #ifdef HAVE_PRCTL
 # include <sys/prctl.h>
 #endif
+#include <asm/unistd.h>
 
+#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;