toos: argdist: support [-t TID] filter
authorzhenwei pi <pizhenwei@bytedance.com>
Mon, 6 Sep 2021 10:28:16 +0000 (18:28 +0800)
committeryonghong-song <ys114321@gmail.com>
Wed, 8 Sep 2021 01:47:54 +0000 (18:47 -0700)
It's helpful to measure argdist in multi-thread case, so we can
distinguish workload is balanced of not.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
man/man8/argdist.8
tools/argdist.py
tools/argdist_example.txt

index 4116cd4d2e5fa654712de09517255be636695137..3033571b5fdb046618436320a5ca08b34fa39403 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 argdist \- Trace a function and display a histogram or frequency count of its parameter values. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B argdist [-h] [-p PID] [-z STRING_SIZE] [-i INTERVAL] [-d DURATION] [-n COUNT] [-v] [-T TOP] [-H specifier] [-C specifier] [-I header]
+.B argdist [-h] [-p PID] [-z STRING_SIZE] [-i INTERVAL] [-d DURATION] [-n COUNT] [-v] [-T TOP] [-H specifier] [-C specifier] [-I header] [-t TID]
 .SH DESCRIPTION
 argdist attaches to function entry and exit points, collects specified parameter
 values, and stores them in a histogram or a frequency collection that counts
@@ -20,6 +20,9 @@ Print usage message.
 \-p PID
 Trace only functions in the process PID.
 .TP
+\-t TID
+Trace only functions in the thread TID.
+.TP
 \-z STRING_SIZE
 When collecting string arguments (of type char*), collect up to STRING_SIZE 
 characters. Longer strings will be truncated.
index b810126ec7e5b391da21a8402fda63dc113c8a41..83a66f369c6722646bd79aed5ad929787e11df06 100755 (executable)
@@ -5,6 +5,7 @@
 #
 # USAGE: argdist [-h] [-p PID] [-z STRING_SIZE] [-i INTERVAL] [-n COUNT] [-v]
 #                [-c] [-T TOP] [-C specifier] [-H specifier] [-I header]
+#                [-t TID]
 #
 # Licensed under the Apache License, Version 2.0 (the "License")
 # Copyright (C) 2016 Sasha Goldshtein.
@@ -55,6 +56,7 @@ int PROBENAME(struct pt_regs *ctx SIGNATURE)
         u32 __pid      = __pid_tgid;        // lower 32 bits
         u32 __tgid     = __pid_tgid >> 32;  // upper 32 bits
         PID_FILTER
+        TID_FILTER
         COLLECT
         return 0;
 }
@@ -63,6 +65,7 @@ int PROBENAME(struct pt_regs *ctx SIGNATURE)
                 text = text.replace("SIGNATURE",
                      "" if len(self.signature) == 0 else ", " + self.signature)
                 text = text.replace("PID_FILTER", self._generate_pid_filter())
+                text = text.replace("TID_FILTER", self._generate_tid_filter())
                 collect = ""
                 for pname in self.args_to_probe:
                         param_hash = self.hashname_prefix + pname
@@ -184,6 +187,7 @@ u64 __time = bpf_ktime_get_ns();
                 self.usdt_ctx = None
                 self.streq_functions = ""
                 self.pid = tool.args.pid
+                self.tid = tool.args.tid
                 self.cumulative = tool.args.cumulative or False
                 self.raw_spec = specifier
                 self.probe_user_list = set()
@@ -348,6 +352,12 @@ u64 __time = bpf_ktime_get_ns();
                 else:
                         return ""
 
+        def _generate_tid_filter(self):
+                if self.tid is not None and not self.is_user:
+                        return "if (__pid != %d) { return 0; }" % self.tid
+                else:
+                        return ""
+
         def generate_text(self):
                 program = ""
                 probe_text = """
@@ -362,6 +372,7 @@ DATA_DECL
         u32 __pid      = __pid_tgid;        // lower 32 bits
         u32 __tgid     = __pid_tgid >> 32;  // upper 32 bits
         PID_FILTER
+        TID_FILTER
         PREFIX
         KEY_EXPR
         if (!(FILTER)) return 0;
@@ -391,6 +402,8 @@ DATA_DECL
                 program = program.replace("SIGNATURE", signature)
                 program = program.replace("PID_FILTER",
                                           self._generate_pid_filter())
+                program = program.replace("TID_FILTER",
+                                          self._generate_tid_filter())
 
                 decl = self._generate_hash_decl()
                 key_expr = self._generate_key_assignment()
@@ -602,6 +615,8 @@ argdist -I 'kernel/sched/sched.h' \\
                   epilog=Tool.examples)
                 parser.add_argument("-p", "--pid", type=int,
                   help="id of the process to trace (optional)")
+                parser.add_argument("-t", "--tid", type=int,
+                  help="id of the thread to trace (optional)")
                 parser.add_argument("-z", "--string-size", default=80,
                   type=int,
                   help="maximum string size to read from char* arguments")
index 9ddfad3d937616ba9a7c6c707a5c6578688a9447..5ee00786c2914a80726b7ec08c72b34b04d8722e 100644 (file)
@@ -345,6 +345,7 @@ Trace a function and display a summary of its parameter values.
 optional arguments:
   -h, --help            show this help message and exit
   -p PID, --pid PID     id of the process to trace (optional)
+  -t TID, --tid TID     id of the thread to trace (optional)
   -z STRING_SIZE, --string-size STRING_SIZE
                         maximum string size to read from char* arguments
   -i INTERVAL, --interval INTERVAL