Commit d2f4762a authored by Sasha Goldshtein's avatar Sasha Goldshtein Committed by 4ast

argdist: Cumulative mode (-c) (#719)

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