Feature requests: list of PIDS, and all threads
George Spelvin
linux at horizon.com
Fri Mar 9 16:22:19 UTC 2012
Thank you very much!
> +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;
> + }
> +}
> +
I probably would have used strtoul(), to get automatic whitespace skipping:
(WARNING: Untested code.)
+static void process_opt_p_list(char *opt)
+{
+ do {
+ /*
+ * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
+ * pidof uses space as delim, pgrep uses newline. :(
+ */
+ struct tcb *tcp;
+ char *q;
+ unsigned long pid = strtoul(opt, &q, 10);
+
+ if ((pid_t)pid <= 0 || (pid_t)pid != pid || q == opt) {
+ error_msg("Invalid process id: '%s'", opt);
+ return;
+ }
+ if (pid == strace_tracer_pid) {
+ error_msg("I'm sorry, I can't let you do that, Dave.");
+ return;
+ }
+ 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++;
+
+ opt = q + strspn(q, ", \n\t");
+ } while (*opt);
+}
+
An interesting question is whether zero pids in the PID list should be
permitted. I changed the loop above to forbid it.
I'd also recommend updating the documentation:
diff --git a/strace.1 b/strace.1
index a98b9f9..a5c98ad 100644
--- a/strace.1
+++ b/strace.1
@@ -531,9 +531,11 @@ at any time by a keyboard interrupt signal (\c
.B strace
will respond by detaching itself from the traced process(es)
leaving it (them) to continue running.
-Multiple
+Up to 32 pids may be listed, using either multiple
.B \-p
-options can be used to attach to up to 32 processes in addition to
+options, or a comma or whitespace separated list to a single
+.B \-p
+option, in addition to the
.I command
(which is optional if at least one
.B \-p
(Both contributions released to the public domain, or licensed under CC0
in the alternative, I fart in the general direction of copyright lawyers,
yadda yadda.)
Some documentation for the all-threads behaviour of -f would also be
nice, but I'm not quite certain I understand it well enough to document
it accurately. It seems to depend on LINUX && !daemonized_tracer.
I have no idea why the latter is an issue; when strace attaches in the
-D case, the target process is single-threaded. I'm also not sure how
the code avoids attaching to the master task twice; It seems to attach
to /proc/$$/task/*, which normally includes /proc/$$/task/$$, and then
to $$ again.
More information about the Strace-devel
mailing list