]> granicus.if.org Git - strace/blobdiff - strace.c
tests: check decoding of netlink smc_diag_msg attributes
[strace] / strace.c
index 3af9e4fb0636e215b3590e67f12d716e019123f2..955a1c9f5e0b2ac42ba01f3a8aee5a2f1c2058a1 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -57,7 +57,7 @@ extern char *optarg;
 
 #ifdef USE_LIBUNWIND
 /* if this is true do the stack trace for every system call */
-bool stack_trace_enabled = false;
+bool stack_trace_enabled;
 #endif
 
 #define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
@@ -74,27 +74,27 @@ bool stack_trace_enabled = false;
 const unsigned int syscall_trap_sig = SIGTRAP | 0x80;
 
 cflag_t cflag = CFLAG_NONE;
-unsigned int followfork = 0;
+unsigned int followfork;
 unsigned int ptrace_setoptions = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC
                                 | PTRACE_O_TRACEEXIT;
-unsigned int xflag = 0;
-bool debug_flag = 0;
-bool Tflag = 0;
-bool iflag = 0;
-bool count_wallclock = 0;
-unsigned int qflag = 0;
-static unsigned int tflag = 0;
-static bool rflag = 0;
-static bool print_pid_pfx = 0;
+unsigned int xflag;
+bool debug_flag;
+bool Tflag;
+bool iflag;
+bool count_wallclock;
+unsigned int qflag;
+static unsigned int tflag;
+static bool rflag;
+static bool print_pid_pfx;
 
 /* -I n */
 enum {
-    INTR_NOT_SET        = 0,
-    INTR_ANYWHERE       = 1, /* don't block/ignore any signals */
-    INTR_WHILE_WAIT     = 2, /* block fatal signals while decoding syscall. default */
-    INTR_NEVER          = 3, /* block fatal signals. default if '-o FILE PROG' */
-    INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
-    NUM_INTR_OPTS
+       INTR_NOT_SET        = 0,
+       INTR_ANYWHERE       = 1, /* don't block/ignore any signals */
+       INTR_WHILE_WAIT     = 2, /* block fatal signals while decoding syscall. default */
+       INTR_NEVER          = 3, /* block fatal signals. default if '-o FILE PROG' */
+       INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
+       NUM_INTR_OPTS
 };
 static int opt_intr;
 /* We play with signal mask only if this mode is active: */
@@ -112,7 +112,7 @@ static int opt_intr;
  * wait() etc. Without -D, strace process gets lodged in between,
  * disrupting parent<->child link.
  */
-static bool daemonized_tracer = 0;
+static bool daemonized_tracer;
 
 #if USE_SEIZE
 static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
@@ -123,18 +123,18 @@ static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
 #endif
 
 /* Sometimes we want to print only succeeding syscalls. */
-bool not_failing_only = 0;
+bool not_failing_only;
 
 /* Show path associated with fd arguments */
-unsigned int show_fd_path = 0;
+unsigned int show_fd_path;
 
-static bool detach_on_execve = 0;
+static bool detach_on_execve;
 
 static int exit_code;
-static int strace_child = 0;
-static int strace_tracer_pid = 0;
+static int strace_child;
+static int strace_tracer_pid;
 
-static char *username = NULL;
+static char *username;
 static uid_t run_uid;
 static gid_t run_gid;
 
@@ -142,16 +142,19 @@ unsigned int max_strlen = DEFAULT_STRLEN;
 static int acolumn = DEFAULT_ACOLUMN;
 static char *acolumn_spaces;
 
-static char *outfname = NULL;
+static char *outfname;
 /* If -ff, points to stderr. Else, it's our common output log */
 static FILE *shared_log;
 
-struct tcb *printing_tcp = NULL;
+struct tcb *printing_tcp;
 static struct tcb *current_tcp;
 
 static struct tcb **tcbtab;
 static unsigned int nprocs, tcbtabsize;
-static const char *progname;
+
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+char *program_invocation_name;
+#endif
 
 unsigned os_release; /* generated from uname()'s u.release */
 
@@ -298,13 +301,15 @@ static void verror_msg(int err_no, const char *fmt, va_list p)
        msg = NULL;
        if (vasprintf(&msg, fmt, p) >= 0) {
                if (err_no)
-                       fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
+                       fprintf(stderr, "%s: %s: %s\n",
+                               program_invocation_name, msg, strerror(err_no));
                else
-                       fprintf(stderr, "%s: %s\n", progname, msg);
+                       fprintf(stderr, "%s: %s\n",
+                               program_invocation_name, msg);
                free(msg);
        } else {
                /* malloc in vasprintf failed, try it without malloc */
-               fprintf(stderr, "%s: ", progname);
+               fprintf(stderr, "%s: ", program_invocation_name);
                vfprintf(stderr, fmt, p);
                if (err_no)
                        fprintf(stderr, ": %s\n", strerror(err_no));
@@ -339,7 +344,8 @@ void error_msg_and_help(const char *fmt, ...)
                va_start(p, fmt);
                verror_msg(0, fmt, p);
        }
-       fprintf(stderr, "Try '%s -h' for more information.\n", progname);
+       fprintf(stderr, "Try '%s -h' for more information.\n",
+               program_invocation_name);
        die();
 }
 
@@ -520,7 +526,7 @@ strace_fopen(const char *path)
        return fp;
 }
 
-static int popen_pid = 0;
+static int popen_pid;
 
 #ifndef _PATH_BSHELL
 # define _PATH_BSHELL "/bin/sh"
@@ -566,7 +572,7 @@ strace_popen(const char *command)
        swap_uid();
        fp = fdopen(fds[1], "w");
        if (!fp)
-               die_out_of_memory();
+               perror_msg_and_die("fdopen");
        return fp;
 }
 
@@ -690,12 +696,10 @@ printleader(struct tcb *tcp)
                        tprintf("%6ld.%06ld ",
                                (long) dtv.tv_sec, (long) dtv.tv_usec);
                        otv = tv;
-               }
-               else if (tflag > 2) {
+               } else if (tflag > 2) {
                        tprintf("%ld.%06ld ",
                                (long) tv.tv_sec, (long) tv.tv_usec);
-               }
-               else {
+               } else {
                        time_t local = tv.tv_sec;
                        strftime(str, sizeof(str), "%T", localtime(&local));
                        if (tflag > 1)
@@ -919,8 +923,7 @@ detach(struct tcb *tcp)
                        goto wait_loop;
                if (errno != ESRCH)
                        perror_msg("detach: ptrace(PTRACE_INTERRUPT,%u)", tcp->pid);
-       }
-       else {
+       } else {
                error = my_tkill(tcp->pid, SIGSTOP);
                if (!error)
                        goto wait_loop;
@@ -1032,7 +1035,7 @@ process_opt_p_list(char *opt)
                 * pidof uses space as delim, pgrep uses newline. :(
                 */
                int pid;
-               char *delim = opt + strcspn(opt, ", \n\t");
+               char *delim = opt + strcspn(opt, "\n\t ,");
                char c = *delim;
 
                *delim = '\0';
@@ -1231,8 +1234,7 @@ exec_or_die(void)
                if (setreuid(run_uid, params->run_euid) < 0) {
                        perror_msg_and_die("setreuid");
                }
-       }
-       else if (geteuid() != 0)
+       } else if (geteuid() != 0)
                if (setreuid(run_uid, run_uid) < 0) {
                        perror_msg_and_die("setreuid");
                }
@@ -1364,15 +1366,13 @@ startup_child(char **argv)
                        if (colon) {
                                n = colon - path;
                                m = n + 1;
-                       }
-                       else
+                       } else
                                m = n = strlen(path);
                        if (n == 0) {
                                if (!getcwd(pathname, PATH_MAX))
                                        continue;
                                len = strlen(pathname);
-                       }
-                       else if (n > sizeof(pathname) - 1)
+                       } else if (n > sizeof(pathname) - 1)
                                continue;
                        else {
                                strncpy(pathname, path, n);
@@ -1466,8 +1466,7 @@ startup_child(char **argv)
                            | TCB_SKIP_DETACH_ON_FIRST_EXEC
                            | (NOMMU_SYSTEM ? 0 : (TCB_HIDE_LOG | post_attach_sigstop));
                newoutf(tcp);
-       }
-       else {
+       } else {
                /* With -D, we are *child* here, the tracee is our parent. */
                strace_child = strace_tracer_pid;
                strace_tracer_pid = getpid();
@@ -1582,12 +1581,12 @@ get_os_release(void)
                        error_msg_and_die("Bad OS release string: '%s'", u.release);
                /* Note: this open-codes KERNEL_VERSION(): */
                rel = (rel << 8) | atoi(p);
-               if (rel >= KERNEL_VERSION(1,0,0))
+               if (rel >= KERNEL_VERSION(1, 0, 0))
                        break;
                while (*p >= '0' && *p <= '9')
                        p++;
                if (*p != '.') {
-                       if (rel >= KERNEL_VERSION(0,1,0)) {
+                       if (rel >= KERNEL_VERSION(0, 1, 0)) {
                                /* "X.Y-something" means "X.Y.0" */
                                rel <<= 8;
                                break;
@@ -1624,7 +1623,11 @@ init(int argc, char *argv[])
        int c, i;
        int optF = 0;
 
-       progname = argv[0] ? argv[0] : "strace";
+       if (!program_invocation_name || !*program_invocation_name) {
+               static char name[] = "strace";
+               program_invocation_name =
+                       (argv[0] && *argv[0]) ? argv[0] : name;
+       }
 
        strace_tracer_pid = getpid();
 
@@ -1740,7 +1743,7 @@ init(int argc, char *argv[])
                        break;
                case 's':
                        i = string_to_uint(optarg);
-                       if (i < 0)
+                       if (i < 0 || (unsigned int) i > -1U / 4)
                                error_opt_arg(c, optarg);
                        max_strlen = i;
                        break;
@@ -1757,7 +1760,7 @@ init(int argc, char *argv[])
 #endif
                case 'E':
                        if (putenv(optarg) < 0)
-                               die_out_of_memory();
+                               perror_msg_and_die("putenv");
                        break;
                case 'I':
                        opt_intr = string_to_uint_upto(optarg, NUM_INTR_OPTS - 1);
@@ -1769,14 +1772,11 @@ init(int argc, char *argv[])
                        break;
                }
        }
-       argv += optind;
-       /* argc -= optind; - no need, argc is not used below */
 
-       acolumn_spaces = xmalloc(acolumn + 1);
-       memset(acolumn_spaces, ' ', acolumn);
-       acolumn_spaces[acolumn] = '\0';
+       argv += optind;
+       argc -= optind;
 
-       if (!argv[0] && !nprocs) {
+       if (argc < 0 || (!argv[0] && !nprocs)) {
                error_msg_and_help("must have PROG [ARGS] or -p PID");
        }
 
@@ -1818,6 +1818,10 @@ init(int argc, char *argv[])
                tflag = 1;
        }
 
+       acolumn_spaces = xmalloc(acolumn + 1);
+       memset(acolumn_spaces, ' ', acolumn);
+       acolumn_spaces[acolumn] = '\0';
+
        sigprocmask(SIG_SETMASK, NULL, &start_set);
        memcpy(&blocked_set, &start_set, sizeof(blocked_set));
 
@@ -1847,8 +1851,7 @@ init(int argc, char *argv[])
                }
                run_uid = pent->pw_uid;
                run_gid = pent->pw_gid;
-       }
-       else {
+       } else {
                run_uid = getuid();
                run_gid = getgid();
        }
@@ -1885,8 +1888,7 @@ init(int argc, char *argv[])
                        if (followfork >= 2)
                                error_msg_and_help("piping the output and -ff are mutually exclusive");
                        shared_log = strace_popen(outfname + 1);
-               }
-               else if (followfork < 2)
+               } else if (followfork < 2)
                        shared_log = strace_fopen(outfname);
        } else {
                /* -ff without -o FILE is the same as single -f */
@@ -2319,7 +2321,7 @@ next_event(int *pstatus, siginfo_t *si)
 
        /*
         * Used to exit simply when nprocs hits zero, but in this testcase:
-        *  int main() { _exit(!!fork()); }
+        *  int main(void) { _exit(!!fork()); }
         * under strace -f, parent sometimes (rarely) manages
         * to exit before we see the first stop of the child,
         * and we are losing track of it:
@@ -2563,7 +2565,7 @@ dispatch_event(enum trace_event ret, int *pstatus, siginfo_t *si)
                 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
                 * On 2.6 and earlier, it can return garbage.
                 */
-               if (os_release >= KERNEL_VERSION(3,0,0))
+               if (os_release >= KERNEL_VERSION(3, 0, 0))
                        current_tcp = maybe_switch_tcbs(current_tcp, current_tcp->pid);
 
                if (detach_on_execve) {
@@ -2594,7 +2596,7 @@ dispatch_event(enum trace_event ret, int *pstatus, siginfo_t *si)
 }
 
 #ifdef ENABLE_COVERAGE_GCOV
-extern void __gcov_flush();
+extern void __gcov_flush(void);
 #endif
 
 static void ATTRIBUTE_NORETURN