argdist: Cumulative mode (-c) (#719)
authorSasha Goldshtein <goldshtn@gmail.com>
Tue, 4 Oct 2016 15:40:15 +0000 (18:40 +0300)
committer4ast <alexei.starovoitov@gmail.com>
Tue, 4 Oct 2016 15:40:15 +0000 (08:40 -0700)
By default, argdist now clears the histograms or freq
count maps after each display interval. The new `-c`
option enables cumulative mode, where maps are not
cleared at each interval. This fixes #718.

tools/argdist.py
tools/argdist_example.txt

index 12edded..b49d549 100755 (executable)
@@ -4,7 +4,7 @@
 #           parameter values as a histogram or frequency count.
 #
 # USAGE: argdist [-h] [-p PID] [-z STRING_SIZE] [-i INTERVAL]
-#                [-n COUNT] [-v] [-T TOP]
+#                [-n COUNT] [-v] [-c] [-T TOP]
 #                [-C specifier [specifier ...]]
 #                [-H specifier [specifier ...]]
 #                [-I header [header ...]]
@@ -178,6 +178,7 @@ u64 __time = bpf_ktime_get_ns();
         def __init__(self, tool, type, specifier):
                 self.usdt_ctx = None
                 self.pid = tool.args.pid
+                self.cumulative = tool.args.cumulative or False
                 self.raw_spec = specifier
                 self._validate_specifier()
 
@@ -451,10 +452,10 @@ int PROBENAME(struct pt_regs *ctx SIGNATURE)
                 if self.type == "freq":
                         print(self.label or self.raw_spec)
                         print("\t%-10s %s" % ("COUNT", "EVENT"))
-                        data = sorted(data.items(), key=lambda kv: kv[1].value)
+                        sdata = sorted(data.items(), key=lambda kv: kv[1].value)
                         if top is not None:
-                                data = data[-top:]
-                        for key, value in data:
+                                sdata = sdata[-top:]
+                        for key, value in sdata:
                                 # Print some nice values if the user didn't
                                 # specify an expression to probe
                                 if self.is_default_expr:
@@ -471,6 +472,8 @@ int PROBENAME(struct pt_regs *ctx SIGNATURE)
                         label = self.label or (self._display_expr(0)
                                 if not self.is_default_expr  else "retval")
                         data.print_log2_hist(val_type=label)
+                if not self.cumulative:
+                        data.clear()
 
         def __str__(self):
                 return self.label or self.raw_spec
@@ -571,6 +574,8 @@ argdist -p 2780 -z 120 \\
                   help="number of outputs")
                 parser.add_argument("-v", "--verbose", action="store_true",
                   help="print resulting BPF program code before executing")
+                parser.add_argument("-c", "--cumulative", action="store_true",
+                  help="do not clear histograms and freq counts at each interval")
                 parser.add_argument("-T", "--top", type=int,
                   help="number of top results to show (not applicable to " +
                   "histograms)")
index d851337..789bd3a 100644 (file)
@@ -10,7 +10,7 @@ various functions.
 For example, suppose you want to find what allocation sizes are common in
 your application:
 
-# ./argdist -p 2420 -C 'p:c:malloc(size_t size):size_t:size'
+# ./argdist -p 2420 -c -C 'p:c:malloc(size_t size):size_t:size'
 [01:42:29]
 p:c:malloc(size_t size):size_t:size
         COUNT      EVENT
@@ -43,7 +43,7 @@ probed and its value was 16, repeatedly.
 Now, suppose you wanted a histogram of buffer sizes passed to the write()
 function across the system:
 
-# ./argdist -H 'p:c:write(int fd, void *buf, size_t len):size_t:len'
+# ./argdist -c -H 'p:c:write(int fd, void *buf, size_t len):size_t:len'
 [01:45:22]
 p:c:write(int fd, void *buf, size_t len):size_t:len
      len                 : count     distribution
@@ -81,7 +81,7 @@ bytes, medium writes of 32-63 bytes, and larger writes of 64-127 bytes.
 But these are writes across the board -- what if you wanted to focus on writes
 to STDOUT?
 
-# ./argdist -H 'p:c:write(int fd, void *buf, size_t len):size_t:len:fd==1'
+# ./argdist -c -H 'p:c:write(int fd, void *buf, size_t len):size_t:len:fd==1'
 [01:47:17]
 p:c:write(int fd, void *buf, size_t len):size_t:len:fd==1
      len                 : count     distribution
@@ -232,7 +232,7 @@ multiple microseconds per byte.
 You could also group results by more than one field. For example, __kmalloc
 takes an additional flags parameter that describes how to allocate memory:
 
-# ./argdist -C 'p::__kmalloc(size_t size, gfp_t flags):gfp_t,size_t:flags,size'
+# ./argdist -c -C 'p::__kmalloc(size_t size, gfp_t flags):gfp_t,size_t:flags,size'
 [03:42:29]
 p::__kmalloc(size_t size, gfp_t flags):gfp_t,size_t:flags,size
         COUNT      EVENT
@@ -268,7 +268,7 @@ between kernel versions like function signatures tend to. For example, let's
 trace the net:net_dev_start_xmit tracepoint and print the interface name that
 is transmitting:
 
-# argdist -C 't:net:net_dev_start_xmit(void *a, void *b, struct net_device *c):char*:c->name' -n 2
+# argdist -c -C 't:net:net_dev_start_xmit(void *a, void *b, struct net_device *c):char*:c->name' -n 2
 [05:01:10]
 t:net:net_dev_start_xmit(void *a, void *b, struct net_device *c):char*:c->name
         COUNT      EVENT
@@ -286,7 +286,7 @@ tracepoint is defined in the include/trace/events/net.h header file.
 Here's a final example that finds how many write() system calls are performed
 by each process on the system:
 
-# argdist -C 'p:c:write():int:$PID;write per process' -n 2
+# argdist -c -C 'p:c:write():int:$PID;write per process' -n 2
 [06:47:18]
 write by process
         COUNT      EVENT
@@ -305,8 +305,8 @@ USAGE message:
 
 # argdist -h
 usage: argdist [-h] [-p PID] [-z STRING_SIZE] [-i INTERVAL] [-n COUNT] [-v]
-                  [-T TOP] [-H [specifier [specifier ...]]]
-                  [-C [specifier [specifier ...]]] [-I [header [header ...]]]
+               [-c] [-T TOP] [-H [specifier [specifier ...]]]
+               [-C [specifier [specifier ...]]] [-I [header [header ...]]]
 
 Trace a function and display a summary of its parameter values.
 
@@ -320,6 +320,7 @@ optional arguments:
   -n COUNT, --number COUNT
                         number of outputs
   -v, --verbose         print resulting BPF program code before executing
+  -c, --cumulative      do not clear histograms and freq counts at each interval
   -T TOP, --top TOP     number of top results to show (not applicable to
                         histograms)
   -H [specifier [specifier ...]], --histogram [specifier [specifier ...]]