Added -s switch to perform allocation sampling
diff --git a/tools/memleak.c b/tools/memleak.c
index 03fa242..c00c398 100644
--- a/tools/memleak.c
+++ b/tools/memleak.c
@@ -44,6 +44,15 @@
int alloc_enter(struct pt_regs *ctx, size_t size)
{
+ // Ideally, this should use a random number source, such as
+ // BPF_FUNC_get_prandom_u32, but that's currently not supported
+ // by the bcc front-end.
+ if (SAMPLE_EVERY_N > 1) {
+ u64 ts = bpf_ktime_get_ns();
+ if (ts % SAMPLE_EVERY_N != 0)
+ return 0;
+ }
+
u64 pid = bpf_get_current_pid_tgid();
u64 size64 = size;
sizes.update(&pid, &size64);
diff --git a/tools/memleak.py b/tools/memleak.py
index b966ff0..0180d72 100755
--- a/tools/memleak.py
+++ b/tools/memleak.py
@@ -47,7 +47,7 @@
@staticmethod
def _is_binary_segment(parts):
return len(parts) == 6 and \
- parts[5][0] == '[' and 'x' in parts[1]
+ parts[5][0] != '[' and 'x' in parts[1]
def _get_code_ranges(self):
ranges = {}
@@ -161,6 +161,8 @@
./memleak.py -o 60000
Trace allocations in kernel mode and display a summary of outstanding
allocations that are at least one minute (60 seconds) old
+./memleak.py -s 5
+ Trace roughly every 5th allocation, to reduce overhead
"""
description = """
@@ -184,6 +186,8 @@
help="prune allocations younger than this age in milliseconds")
parser.add_argument("-c", "--command",
help="execute and trace the specified command")
+parser.add_argument("-s", "--sample-rate", default=1,
+ help="sample every N-th allocation to decrease the overhead")
args = parser.parse_args()
@@ -193,6 +197,7 @@
trace_all = args.trace
interval = int(args.interval)
min_age_ns = 1e6 * int(args.older)
+sample_every_n = args.sample_rate
if command is not None:
print("Executing '%s' and tracing the resulting process." % command)
@@ -200,6 +205,7 @@
bpf_source = open("memleak.c").read()
bpf_source = bpf_source.replace("SHOULD_PRINT", "1" if trace_all else "0")
+bpf_source = bpf_source.replace("SAMPLE_EVERY_N", str(sample_every_n))
bpf_program = BPF(text=bpf_source)
diff --git a/tools/memleak_examples.txt b/tools/memleak_examples.txt
index 4217775..9861b18 100644
--- a/tools/memleak_examples.txt
+++ b/tools/memleak_examples.txt
@@ -117,7 +117,7 @@
# ./memleak.py -h
usage: memleak.py [-h] [-p PID] [-t] [-i INTERVAL] [-a] [-o OLDER]
- [-c COMMAND]
+ [-c COMMAND] [-s SAMPLE_RATE]
Trace outstanding memory allocations that weren't freed.
Supports both user-mode allocations made with malloc/free and kernel-mode
@@ -137,6 +137,8 @@
milliseconds
-c COMMAND, --command COMMAND
execute and trace the specified command
+ -s SAMPLE_RATE, --sample-rate SAMPLE_RATE
+ sample every N-th allocation to decrease the overhead
EXAMPLES:
@@ -146,4 +148,6 @@
./memleak.py -p $(pidof allocs) -t
Trace allocations and display each individual call to malloc/free
./memleak.py -p $(pidof allocs) -a -i 10 Trace allocations and display allocated addresses, sizes, and stacks every 10 seconds for outstanding allocations ./memleak.py -c "./allocs" Run the specified command and trace its allocations ./memleak.py Trace allocations in kernel mode and display a summary of outstanding allocations every 5 seconds ./memleak.py -o 60000 Trace allocations in kernel mode and display a summary of outstanding allocations that are at least one minute (60 seconds) old
+./memleak.py -s 5
+ Trace roughly every 5th allocation, to reduce overhead