[PATCH v3 4/7] Implement -Y option for printing command names for PIDs

Masatake YAMATO yamato at redhat.com
Thu Sep 9 13:43:34 UTC 2021


In some applications like qemu-kvm, threads change their
command names to indicate their roles in the application.
Users can access the command name via /proc/$pid/comm.
The command name can be a great hit to understand the application
behavior.

This change introduces -Y,-decode-pid=comm option that enables
printing command names where PIDs appear.

For example (without -Y option):

[pid 254329] ioctl(18, KVM_RUN <unfinished ...>
[pid 254332] ioctl(21, KVM_RUN <unfinished ...>
[pid 254331] ioctl(20, KVM_RUN <unfinished ...>
[pid 254330] ioctl(19, KVM_RUN <unfinished ...>
[pid 254309] poll([{fd=9, events=POLLOUT}], 1, 0) = 1 ...
[pid 254309] poll([{fd=9, events=POLLOUT}], 1, 0) = 1 ...

(with -Y option):

[pid 254329<CPU 0/KVM>] ioctl(18, KVM_RUN <unfinished ...>
[pid 254332<CPU 3/KVM>] ioctl(21, KVM_RUN <unfinished ...>
[pid 254331<CPU 2/KVM>] ioctl(20, KVM_RUN <unfinished ...>
[pid 254330<CPU 1/KVM>] ioctl(19, KVM_RUN <unfinished ...>
[pid 254309<qemu-system-x86>] poll([{fd=9, events=POLLOUT}], 1, 0) = 1 ...
[pid 254309<qemu-system-x86>] poll([{fd=9, events=POLLOUT}], 1, 0) = 1 ...

This change considers only PIDs in the prefixes of trace lines.
Printing command names for PIDs in arguments and return values is
future work.

* src/strace.c (usage): Add help message for the -Y option.
(printleader): Print the command name for the given tcb.
(init): Add -Y,--decode-pids=comm option.
Call `qualify_decode_pid' when one of the options is given.
Call `maybe_load_task_comm' to handle the case the options
coming after -p option.
* src/filter_qualify.c (qualify_decode_pid): Set PID_DECODING_COMM
and PID_DECODING_NS_TRANSLATION flags to pid_decoding if "comm" is given.
* doc/strace.1.in (.SS Output format): document the -Y option.
* NEWS: document the -Y option.

Enabling PID_DECODING_NS_TRANLATION when given "comm" is suggested
by Ákos Uzonyi <uzonyi.akos at gmail.com>.
Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
 NEWS                 |  1 +
 doc/strace.1.in      |  6 ++++++
 src/filter_qualify.c |  2 ++
 src/strace.c         | 44 +++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index df032f85c..68d813c65 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Noteworthy changes in release 5.14 (2021-09-02)
   * Updated lists of BPF_*, IORING_*, MADV_*, MOUNT_ATTR_*, SCTP_*,
     and UFFD_* constants.
   * Updated lists of ioctl commands from Linux 5.14.
+  * Implemented -Y,--decode-pids=comm option for printing command names for PIDs.
 
 * Bug fixes
   * Fixed build using bionic libc.
diff --git a/doc/strace.1.in b/doc/strace.1.in
index 21495dba3..b15f1178d 100644
--- a/doc/strace.1.in
+++ b/doc/strace.1.in
@@ -1087,6 +1087,12 @@ Same as
 .B "\-\-pidns\-translation"
 option.
 .TP
+.B \-Y
+.TQ
+.BR \-\-decode\-pids = comm
+Print command names for PIDs that appear as the prefixes of trace lines.
+Specifying comm implies enabling pidns.
+.TP
 .B \-\-pidns\-translation
 If strace and tracee are in different PID namespaces, print PIDs in
 strace's namespace, too.
diff --git a/src/filter_qualify.c b/src/filter_qualify.c
index 2d0dcc6f4..54d7e0325 100644
--- a/src/filter_qualify.c
+++ b/src/filter_qualify.c
@@ -472,6 +472,8 @@ qualify_decode_pid(const char *const str)
 {
 	if (strcmp(str, "pidns") == 0)
 		pid_decoding |= PID_DECODING_NS_TRANSLATION;
+	else if (strcmp(str, "comm") == 0)
+		pid_decoding |= PID_DECODING_NS_TRANSLATION|PID_DECODING_COMM;
 	else
 		error_msg_and_die("invalid --decode-pids = argument: '%s'", str);
 }
diff --git a/src/strace.c b/src/strace.c
index 5f7951d94..76ff43d22 100644
--- a/src/strace.c
+++ b/src/strace.c
@@ -416,6 +416,9 @@ Output format:\n\
                  descriptors in addition to paths\n\
   --decode-pids=pidns\n\
                  print PIDs in strace's namespace, too\n\
+  -Y, --decode-pids=comm\n\
+                 print command names associated with the pids appeared\n\
+                 as prefixes of trace lines\n\
 "
 #ifdef ENABLE_SECONTEXT
 "\
@@ -796,10 +799,17 @@ printleader(struct tcb *tcp)
 	set_current_tcp(tcp);
 	current_tcp->curcol = 0;
 
-	if (print_pid_pfx)
-		tprintf("%-5d ", tcp->pid);
-	else if (nprocs > 1 && !outfname)
-		tprintf("[pid %5u] ", tcp->pid);
+	if (print_pid_pfx) {
+		if (pid_decoding & PID_DECODING_COMM)
+			tprintf("%-5d<%s> ", tcp->pid, tcp->comm);
+		else
+			tprintf("%-5d ", tcp->pid);
+	} else if (nprocs > 1 && !outfname) {
+		if (pid_decoding & PID_DECODING_COMM)
+			tprintf("[pid %5u<%s>] ", tcp->pid, tcp->comm);
+		else
+			tprintf("[pid %5u] ", tcp->pid);
+	}
 
 #ifdef ENABLE_SECONTEXT
 	char *context;
@@ -2027,6 +2037,7 @@ init(int argc, char *argv[])
 	static const char qqqflag_qual[] = "all";
 	static const char yflag_qual[] = "path";
 	static const char yyflag_qual[] = "all";
+	static const char Yflag_qual[] = "comm";
 	static const char tflag_str[] = "format:time";
 	static const char ttflag_str[] = "precision:us,format:time";
 	static const char tttflag_str[] = "format:unix,precision:us";
@@ -2039,6 +2050,7 @@ init(int argc, char *argv[])
 	int qflag_short = 0;
 	int followfork_short = 0;
 	int yflag_short = 0;
+	int Yflag_short = 0;
 	bool tflag_long_set = false;
 	int tflag_short = 0;
 	bool columns_set = false;
@@ -2095,7 +2107,7 @@ init(int argc, char *argv[])
 	qualify_signals("all");
 
 	static const char optstring[] =
-		"+a:Ab:cCdDe:E:fFhiI:kno:O:p:P:qrs:S:tTu:U:vVwxX:yzZ";
+		"+a:Ab:cCdDe:E:fFhiI:kno:O:p:P:qrs:S:tTu:U:vVwxX:yYzZ";
 
 	enum {
 		GETOPT_SECCOMP = 0x100,
@@ -2381,6 +2393,9 @@ init(int argc, char *argv[])
 		case 'y':
 			yflag_short++;
 			break;
+		case 'Y':
+			Yflag_short++;
+			break;
 		case GETOPT_PIDNS_TRANSLATION:
 			qualify_decode_pid("pidns");
 			break;
@@ -2510,6 +2525,25 @@ init(int argc, char *argv[])
 		qualify_decode_fd(yflag_short == 1 ? yflag_qual : yyflag_qual);
 	}
 
+	if (Yflag_short) {
+		if (pid_decoding) {
+			error_msg_and_die("-Y and --decode-pids cannot"
+					  " be provided simultaneously");
+		}
+
+		qualify_decode_pid(Yflag_qual);
+	}
+	/*
+	 * If --decode-pids=comm option comes after -p, comm fields of tcbs
+	 * are not filled though tcbs are initialized. We must fill the
+	 * fields here.
+	 */
+	for (unsigned int i = 0; i < tcbtabsize; ++i) {
+		struct tcb *tcp = tcbtab[i];
+		if (tcp->comm[0] == 0)
+			maybe_load_task_comm(tcp);
+	}
+
 	if (seccomp_filtering && detach_on_execve) {
 		error_msg("--seccomp-bpf is not enabled because"
 			  " it is not compatible with -b");
-- 
2.31.1



More information about the Strace-devel mailing list