Skip to content

Commit

Permalink
argdist: Cumulative mode (-c) (iovisor#719)
Browse files Browse the repository at this point in the history
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 iovisor#718.
  • Loading branch information
goldshtn authored and 4ast committed Oct 4, 2016
1 parent f733cac commit d2f4762
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
13 changes: 9 additions & 4 deletions tools/argdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ...]]
Expand Down Expand Up @@ -178,6 +178,7 @@ def _parse_exprs(self, exprs):
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()

Expand Down Expand Up @@ -451,10 +452,10 @@ def display(self, top):
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:
Expand All @@ -471,6 +472,8 @@ def display(self, top):
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
Expand Down Expand Up @@ -571,6 +574,8 @@ def __init__(self):
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)")
Expand Down
17 changes: 9 additions & 8 deletions tools/argdist_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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.

Expand All @@ -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 ...]]
Expand Down

0 comments on commit d2f4762

Please sign in to comment.