]> granicus.if.org Git - strace/blobdiff - strace.c
tests: add a test for -yy option
[strace] / strace.c
index 0f7f16c833187c0ad635d66e0e4879586620f2c1..cb9675856fda13360e735e50a2347a83397ffe3f 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -129,7 +129,7 @@ static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
 bool not_failing_only = 0;
 
 /* Show path associated with fd arguments */
-bool show_fd_path = 0;
+unsigned int show_fd_path = 0;
 
 static bool detach_on_execve = 0;
 /* Are we "strace PROG" and need to skip detach on first execve? */
@@ -216,6 +216,7 @@ usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
 -v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
 -y -- print paths associated with file descriptor arguments\n\
+-yy -- print ip:port pairs associated with socket file descriptors\n\
 -h -- print help message, -V -- print version\n\
 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
 -b execve -- detach on this syscall\n\
@@ -238,7 +239,7 @@ usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
 -P path -- trace accesses to path\n\
 "
 #ifdef USE_LIBUNWIND
-"-k obtain stack trace between each syscall\n\
+"-k obtain stack trace between each syscall (experimental)\n\
 "
 #endif
 /* ancient, no one should use it
@@ -675,7 +676,7 @@ expand_tcbtab(void)
           callers have pointers and it would be a pain.
           So tcbtab is a table of pointers.  Since we never
           free the TCBs, we allocate a single chunk of many.  */
-       int i = tcbtabsize;
+       unsigned int i = tcbtabsize;
        struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
        struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
        if (!newtab || !newtcbs)
@@ -689,7 +690,7 @@ expand_tcbtab(void)
 static struct tcb *
 alloctcb(int pid)
 {
-       int i;
+       unsigned int i;
        struct tcb *tcp;
 
        if (nprocs == tcbtabsize)
@@ -706,7 +707,7 @@ alloctcb(int pid)
 
 #ifdef USE_LIBUNWIND
                        if (stack_trace_enabled)
-                               init_libunwind_ui(tcp);
+                               unwind_tcb_init(tcp);
 #endif
 
                        nprocs++;
@@ -724,6 +725,12 @@ droptcb(struct tcb *tcp)
        if (tcp->pid == 0)
                return;
 
+#ifdef USE_LIBUNWIND
+       if (stack_trace_enabled) {
+               unwind_tcb_fin(tcp);
+       }
+#endif
+
        nprocs--;
        if (debug_flag)
                fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
@@ -745,11 +752,6 @@ droptcb(struct tcb *tcp)
        if (printing_tcp == tcp)
                printing_tcp = NULL;
 
-#ifdef USE_LIBUNWIND
-       if (stack_trace_enabled) {
-               free_libunwind_ui(tcp);
-       }
-#endif
        memset(tcp, 0, sizeof(*tcp));
 }
 
@@ -836,7 +838,7 @@ detach(struct tcb *tcp)
         * 3. Attach SIGSTOP was already pending (TCB_IGNORE_ONE_SIGSTOP set)
         */
        for (;;) {
-               int sig;
+               unsigned int sig;
                if (waitpid(tcp->pid, &status, __WALL) < 0) {
                        if (errno == EINTR)
                                continue;
@@ -953,7 +955,7 @@ process_opt_p_list(char *opt)
 static void
 startup_attach(void)
 {
-       int tcbi;
+       unsigned int tcbi;
        struct tcb *tcp;
 
        /*
@@ -1182,7 +1184,7 @@ startup_child(char **argv)
 #endif /* USE_DEBUGGING_EXEC */
        else {
                const char *path;
-               int m, n, len;
+               size_t m, n, len;
 
                for (path = getenv("PATH"); path && *path; path += m) {
                        const char *colon = strchr(path, ':');
@@ -1634,6 +1636,7 @@ init(int argc, char *argv[])
        struct tcb *tcp;
        int c, i;
        int optF = 0;
+       unsigned int tcbi;
        struct sigaction sa;
 
        progname = argv[0] ? argv[0] : "strace";
@@ -1657,8 +1660,8 @@ init(int argc, char *argv[])
        tcp = calloc(tcbtabsize, sizeof(*tcp));
        if (!tcp)
                die_out_of_memory();
-       for (c = 0; c < tcbtabsize; c++)
-               tcbtab[c] = tcp++;
+       for (tcbi = 0; tcbi < tcbtabsize; tcbi++)
+               tcbtab[tcbi] = tcp++;
 
        shared_log = stderr;
        set_sortby(DEFAULT_SORTBY);
@@ -1733,7 +1736,7 @@ init(int argc, char *argv[])
                        xflag++;
                        break;
                case 'y':
-                       show_fd_path = 1;
+                       show_fd_path++;
                        break;
                case 'v':
                        qualify("abbrev=none");
@@ -1816,11 +1819,6 @@ init(int argc, char *argv[])
                error_msg_and_die("-D and -p are mutually exclusive");
        }
 
-#ifdef USE_LIBUNWIND
-       if (stack_trace_enabled)
-               init_unwind_addr_space();
-#endif
-
        if (!followfork)
                followfork = optF;
 
@@ -1832,6 +1830,28 @@ init(int argc, char *argv[])
                error_msg_and_die("-w must be given with (-c or -C)");
        }
 
+       if (cflag == CFLAG_ONLY_STATS) {
+               if (iflag)
+                       error_msg("-%c has no effect with -c", 'i');
+#ifdef USE_LIBUNWIND
+               if (stack_trace_enabled)
+                       error_msg("-%c has no effect with -c", 'k');
+#endif
+               if (rflag)
+                       error_msg("-%c has no effect with -c", 'r');
+               if (tflag)
+                       error_msg("-%c has no effect with -c", 't');
+               if (Tflag)
+                       error_msg("-%c has no effect with -c", 'T');
+               if (show_fd_path)
+                       error_msg("-%c has no effect with -c", 'y');
+       }
+
+#ifdef USE_LIBUNWIND
+       if (stack_trace_enabled)
+               unwind_init();
+#endif
+
        /* See if they want to run as another user. */
        if (username != NULL) {
                struct passwd *pent;
@@ -1960,7 +1980,7 @@ init(int argc, char *argv[])
 static struct tcb *
 pid2tcb(int pid)
 {
-       int i;
+       unsigned int i;
 
        if (pid <= 0)
                return NULL;
@@ -1977,7 +1997,7 @@ pid2tcb(int pid)
 static void
 cleanup(void)
 {
-       int i;
+       unsigned int i;
        struct tcb *tcp;
        int fatal_sig;
 
@@ -2031,10 +2051,11 @@ trace(void)
        while (1) {
                int pid;
                int wait_errno;
-               int status, sig;
+               int status;
                int stopped;
-               struct tcb *tcp;
+               unsigned int sig;
                unsigned event;
+               struct tcb *tcp;
 
                if (interrupted)
                        return;
@@ -2167,10 +2188,10 @@ trace(void)
                        if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0)
                                goto dont_switch_tcbs;
                        /* Avoid truncation in pid2tcb() param passing */
-                       if (old_pid > UINT_MAX)
-                               goto dont_switch_tcbs;
                        if (old_pid <= 0 || old_pid == pid)
                                goto dont_switch_tcbs;
+                       if ((unsigned long) old_pid > UINT_MAX)
+                               goto dont_switch_tcbs;
                        execve_thread = pid2tcb(old_pid);
                        /* It should be !NULL, but I feel paranoid */
                        if (!execve_thread)