From: Denys Vlasenko Date: Fri, 9 Mar 2012 12:01:04 +0000 (+0100) Subject: Allow -p PID to take comma or whitespace-separated list of PIDs X-Git-Tag: v4.7~142 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e8172b79e3dd35a136f4dc4d4de9df5bb4565c01;p=strace Allow -p PID to take comma or whitespace-separated list of PIDs * defs.h: Clarify meaning of TCB_ATTACHED. No code changes. * strace.c (process_opt_p_list): New function. (main): Call process_opt_p_list to process -p PIDs argument. Signed-off-by: Denys Vlasenko --- diff --git a/defs.h b/defs.h index 1f0b7b51..a14950b3 100644 --- a/defs.h +++ b/defs.h @@ -352,7 +352,14 @@ struct tcb { * Use entering(tcp) / exiting(tcp) to check this bit to make code more readable. */ #define TCB_INSYSCALL 00010 -#define TCB_ATTACHED 00020 /* Process is not our own child */ +/* + * Process is not our own child. + * In "strace [-f] PROG" case, traced child (PROG) will have this bit not set, + * but any its children (including threads) will. + * Note: if bit is set, it does *not* mean that attaching was already done. + * There is a small window at the init time when it's not true. + */ +#define TCB_ATTACHED 00020 #define TCB_BPTSET 00100 /* "Breakpoint" set after fork(2) */ #define TCB_REPRINT 01000 /* We should reprint this syscall on exit */ #define TCB_FILTERED 02000 /* This system call has been filtered out */ diff --git a/strace.c b/strace.c index d774611c..5e2f9c6c 100644 --- a/strace.c +++ b/strace.c @@ -420,6 +420,45 @@ newoutf(struct tcb *tcp) } } +static void process_opt_p_list(char *opt) +{ + while (*opt) { + /* + * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`". + * pidof uses space as delim, pgrep uses newline. :( + */ + int pid; + struct tcb *tcp; + char *delim = opt + strcspn(opt, ", \n\t"); + char c = *delim; + + *delim = '\0'; + pid = atoi(opt); /* TODO: stricter parsing of the number? */ + if (pid <= 0) { + error_msg("Invalid process id: '%s'", opt); + *delim = c; + return; + } + if (pid == strace_tracer_pid) { + error_msg("I'm sorry, I can't let you do that, Dave."); + *delim = c; + return; + } + *delim = c; + tcp = alloc_tcb(pid, 0); + tcp->flags |= TCB_ATTACHED; + /* + * pflag_seen says how many PIDs we handled, + * not how many -p opts there were. + * Used to decide whether to print pid prefix in logs. + */ + pflag_seen++; + if (c == '\0') + break; + opt = delim + 1; + } +} + static void startup_attach(void) { @@ -1019,7 +1058,7 @@ int main(int argc, char *argv[]) { struct tcb *tcp; - int c, pid = 0; + int c; int optF = 0; struct sigaction sa; @@ -1126,18 +1165,7 @@ main(int argc, char *argv[]) set_overhead(atoi(optarg)); break; case 'p': - pid = atoi(optarg); - if (pid <= 0) { - error_msg("Invalid process id: '%s'", optarg); - break; - } - if (pid == strace_tracer_pid) { - error_msg("I'm sorry, I can't let you do that, Dave."); - break; - } - tcp = alloc_tcb(pid, 0); - tcp->flags |= TCB_ATTACHED; - pflag_seen++; + process_opt_p_list(optarg); break; case 'P': tracing_paths = 1;