Feature requests: list of PIDS, and all threads

Denys Vlasenko dvlasenk at redhat.com
Fri Mar 9 12:00:41 UTC 2012


On 03/09/2012 12:13 AM, George Spelvin wrote:
>>> 1) Some way to supply a *list* of pids to be traced, without having to
>>>      prefix each with "-p".  This would make it much easier to paste
>>>      in the output of "pgrep" or the like.
>>>
>>>      Two options come to mind:
>>>      -P means "all bare arguments are pids"; the case of mixing
>>>         pids and a commnd line process is somewhat uncommon.
>>>      -p takes a whitespace-separated list of pids.  So I could
>>>         use -p "`pgrep foo`".
>
>> I guess we can support -p PID1,PID2 _and_ -p "PID1 PID2".
>> Why not?
>
> That did seem simplest BUT be sure to accept other whitespace, and in
> particular \n, if you're not relying on the shell to break the list
> into argv[].


--- strace.5/strace.c	2012-02-28 15:37:10.991758554 +0100
+++ strace.6/strace.c	2012-03-09 12:10:08.945758226 +0100
@@ -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;

-- 
vda





More information about the Strace-devel mailing list