xref: /aosp_15_r20/external/bcc/tools/memleak_example.txt (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard WorkerDemonstrations of memleak.
2*387f9dfdSAndroid Build Coastguard Worker
3*387f9dfdSAndroid Build Coastguard Worker
4*387f9dfdSAndroid Build Coastguard Workermemleak traces and matches memory allocation and deallocation requests, and
5*387f9dfdSAndroid Build Coastguard Workercollects call stacks for each allocation. memleak can then print a summary
6*387f9dfdSAndroid Build Coastguard Workerof which call stacks performed allocations that weren't subsequently freed.
7*387f9dfdSAndroid Build Coastguard WorkerFor example:
8*387f9dfdSAndroid Build Coastguard Worker
9*387f9dfdSAndroid Build Coastguard Worker# ./memleak -p $(pidof allocs)
10*387f9dfdSAndroid Build Coastguard WorkerAttaching to pid 5193, Ctrl+C to quit.
11*387f9dfdSAndroid Build Coastguard Worker[11:16:33] Top 2 stacks with outstanding allocations:
12*387f9dfdSAndroid Build Coastguard Worker        80 bytes in 5 allocations from stack
13*387f9dfdSAndroid Build Coastguard Worker                 main+0x6d [allocs]
14*387f9dfdSAndroid Build Coastguard Worker                 __libc_start_main+0xf0 [libc-2.21.so]
15*387f9dfdSAndroid Build Coastguard Worker
16*387f9dfdSAndroid Build Coastguard Worker[11:16:34] Top 2 stacks with outstanding allocations:
17*387f9dfdSAndroid Build Coastguard Worker        160 bytes in 10 allocations from stack
18*387f9dfdSAndroid Build Coastguard Worker                 main+0x6d [allocs]
19*387f9dfdSAndroid Build Coastguard Worker                 __libc_start_main+0xf0 [libc-2.21.so]
20*387f9dfdSAndroid Build Coastguard Worker
21*387f9dfdSAndroid Build Coastguard Worker
22*387f9dfdSAndroid Build Coastguard WorkerEach entry printed is a set of allocations that originate from the same call
23*387f9dfdSAndroid Build Coastguard Workerstack, and that weren't freed yet. The number of bytes and number of allocs
24*387f9dfdSAndroid Build Coastguard Workerare followed by the call stack, top to bottom, of the allocation site.
25*387f9dfdSAndroid Build Coastguard Worker
26*387f9dfdSAndroid Build Coastguard WorkerAs time goes on, it becomes apparent that the main function in the allocs
27*387f9dfdSAndroid Build Coastguard Workerprocess is leaking memory, 16 bytes at a time. Fortunately, you don't have to
28*387f9dfdSAndroid Build Coastguard Workerinspect each allocation individually -- you get a nice summary of which stack
29*387f9dfdSAndroid Build Coastguard Workeris responsible for a large leak.
30*387f9dfdSAndroid Build Coastguard Worker
31*387f9dfdSAndroid Build Coastguard WorkerOccasionally, you do want the individual allocation details. Perhaps the same
32*387f9dfdSAndroid Build Coastguard Workerstack is allocating various sizes and you want to confirm which sizes are
33*387f9dfdSAndroid Build Coastguard Workerprevalent. Use the -a switch:
34*387f9dfdSAndroid Build Coastguard Worker
35*387f9dfdSAndroid Build Coastguard Worker# ./memleak -p $(pidof allocs) -a
36*387f9dfdSAndroid Build Coastguard WorkerAttaching to pid 5193, Ctrl+C to quit.
37*387f9dfdSAndroid Build Coastguard Worker[11:16:33] Top 2 stacks with outstanding allocations:
38*387f9dfdSAndroid Build Coastguard Worker        addr = 948cd0 size = 16
39*387f9dfdSAndroid Build Coastguard Worker        addr = 948d10 size = 16
40*387f9dfdSAndroid Build Coastguard Worker        addr = 948d30 size = 16
41*387f9dfdSAndroid Build Coastguard Worker        addr = 948cf0 size = 16
42*387f9dfdSAndroid Build Coastguard Worker        64 bytes in 4 allocations from stack
43*387f9dfdSAndroid Build Coastguard Worker                 main+0x6d [allocs]
44*387f9dfdSAndroid Build Coastguard Worker                 __libc_start_main+0xf0 [libc-2.21.so]
45*387f9dfdSAndroid Build Coastguard Worker
46*387f9dfdSAndroid Build Coastguard Worker[11:16:34] Top 2 stacks with outstanding allocations:
47*387f9dfdSAndroid Build Coastguard Worker        addr = 948d50 size = 16
48*387f9dfdSAndroid Build Coastguard Worker        addr = 948cd0 size = 16
49*387f9dfdSAndroid Build Coastguard Worker        addr = 948d10 size = 16
50*387f9dfdSAndroid Build Coastguard Worker        addr = 948d30 size = 16
51*387f9dfdSAndroid Build Coastguard Worker        addr = 948cf0 size = 16
52*387f9dfdSAndroid Build Coastguard Worker        addr = 948dd0 size = 16
53*387f9dfdSAndroid Build Coastguard Worker        addr = 948d90 size = 16
54*387f9dfdSAndroid Build Coastguard Worker        addr = 948db0 size = 16
55*387f9dfdSAndroid Build Coastguard Worker        addr = 948d70 size = 16
56*387f9dfdSAndroid Build Coastguard Worker        addr = 948df0 size = 16
57*387f9dfdSAndroid Build Coastguard Worker        160 bytes in 10 allocations from stack
58*387f9dfdSAndroid Build Coastguard Worker                 main+0x6d [allocs]
59*387f9dfdSAndroid Build Coastguard Worker                 __libc_start_main+0xf0 [libc-2.21.so]
60*387f9dfdSAndroid Build Coastguard Worker
61*387f9dfdSAndroid Build Coastguard Worker
62*387f9dfdSAndroid Build Coastguard WorkerWhen using the -p switch, memleak traces the libc allocations of a particular
63*387f9dfdSAndroid Build Coastguard Workerprocess. Without this switch, kernel allocations are traced instead.
64*387f9dfdSAndroid Build Coastguard WorkerFor example:
65*387f9dfdSAndroid Build Coastguard Worker
66*387f9dfdSAndroid Build Coastguard Worker# ./memleak
67*387f9dfdSAndroid Build Coastguard WorkerAttaching to kernel allocators, Ctrl+C to quit.
68*387f9dfdSAndroid Build Coastguard Worker...
69*387f9dfdSAndroid Build Coastguard Worker        248 bytes in 4 allocations from stack
70*387f9dfdSAndroid Build Coastguard Worker                 bpf_prog_load [kernel]
71*387f9dfdSAndroid Build Coastguard Worker                 sys_bpf [kernel]
72*387f9dfdSAndroid Build Coastguard Worker
73*387f9dfdSAndroid Build Coastguard Worker        328 bytes in 1 allocations from stack
74*387f9dfdSAndroid Build Coastguard Worker                 perf_mmap [kernel]
75*387f9dfdSAndroid Build Coastguard Worker                 mmap_region [kernel]
76*387f9dfdSAndroid Build Coastguard Worker                 do_mmap [kernel]
77*387f9dfdSAndroid Build Coastguard Worker                 vm_mmap_pgoff [kernel]
78*387f9dfdSAndroid Build Coastguard Worker                 sys_mmap_pgoff [kernel]
79*387f9dfdSAndroid Build Coastguard Worker                 sys_mmap [kernel]
80*387f9dfdSAndroid Build Coastguard Worker
81*387f9dfdSAndroid Build Coastguard Worker        464 bytes in 1 allocations from stack
82*387f9dfdSAndroid Build Coastguard Worker                 traceprobe_command [kernel]
83*387f9dfdSAndroid Build Coastguard Worker                 traceprobe_probes_write [kernel]
84*387f9dfdSAndroid Build Coastguard Worker                 probes_write [kernel]
85*387f9dfdSAndroid Build Coastguard Worker                 __vfs_write [kernel]
86*387f9dfdSAndroid Build Coastguard Worker                 vfs_write [kernel]
87*387f9dfdSAndroid Build Coastguard Worker                 sys_write [kernel]
88*387f9dfdSAndroid Build Coastguard Worker                 entry_SYSCALL_64_fastpath [kernel]
89*387f9dfdSAndroid Build Coastguard Worker
90*387f9dfdSAndroid Build Coastguard Worker        8192 bytes in 1 allocations from stack
91*387f9dfdSAndroid Build Coastguard Worker                 alloc_and_copy_ftrace_hash.constprop.59 [kernel]
92*387f9dfdSAndroid Build Coastguard Worker                 ftrace_set_hash [kernel]
93*387f9dfdSAndroid Build Coastguard Worker                 ftrace_set_filter_ip [kernel]
94*387f9dfdSAndroid Build Coastguard Worker                 arm_kprobe [kernel]
95*387f9dfdSAndroid Build Coastguard Worker                 enable_kprobe [kernel]
96*387f9dfdSAndroid Build Coastguard Worker                 kprobe_register [kernel]
97*387f9dfdSAndroid Build Coastguard Worker                 perf_trace_init [kernel]
98*387f9dfdSAndroid Build Coastguard Worker                 perf_tp_event_init [kernel]
99*387f9dfdSAndroid Build Coastguard Worker
100*387f9dfdSAndroid Build Coastguard Worker
101*387f9dfdSAndroid Build Coastguard WorkerHere you can see that arming the kprobe to which our eBPF program is attached
102*387f9dfdSAndroid Build Coastguard Workerconsumed 8KB of memory. Loading the BPF program also consumed a couple hundred
103*387f9dfdSAndroid Build Coastguard Workerbytes (in bpf_prog_load).
104*387f9dfdSAndroid Build Coastguard Worker
105*387f9dfdSAndroid Build Coastguard Workermemleak stores each allocated block along with its size, timestamp, and the
106*387f9dfdSAndroid Build Coastguard Workerstack that allocated it. When the block is deleted, this information is freed
107*387f9dfdSAndroid Build Coastguard Workerto reduce the memory overhead.
108*387f9dfdSAndroid Build Coastguard Worker
109*387f9dfdSAndroid Build Coastguard WorkerTo avoid false positives, allocations younger than a certain age (500ms by
110*387f9dfdSAndroid Build Coastguard Workerdefault) are not printed. To change this threshold, use the -o switch.
111*387f9dfdSAndroid Build Coastguard Worker
112*387f9dfdSAndroid Build Coastguard WorkerBy default, memleak prints its output every 5 seconds. To change this
113*387f9dfdSAndroid Build Coastguard Workerinterval, pass the interval as a positional parameter to memleak. You can
114*387f9dfdSAndroid Build Coastguard Workeralso control the number of times the output will be printed before exiting.
115*387f9dfdSAndroid Build Coastguard WorkerFor example:
116*387f9dfdSAndroid Build Coastguard Worker
117*387f9dfdSAndroid Build Coastguard Worker# ./memleak 1 10
118*387f9dfdSAndroid Build Coastguard Worker
119*387f9dfdSAndroid Build Coastguard Worker... will print the outstanding allocation statistics every second, for ten
120*387f9dfdSAndroid Build Coastguard Workertimes, and then exit.
121*387f9dfdSAndroid Build Coastguard Worker
122*387f9dfdSAndroid Build Coastguard Workermemleak may introduce considerable overhead if your application or kernel is
123*387f9dfdSAndroid Build Coastguard Workerallocating and freeing memory at a very high rate. In that case, you can
124*387f9dfdSAndroid Build Coastguard Workercontrol the overhead by sampling every N-th allocation. For example, to sample
125*387f9dfdSAndroid Build Coastguard Workerroughly 10% of the allocations and print the outstanding allocations every 5
126*387f9dfdSAndroid Build Coastguard Workerseconds, 3 times before quitting:
127*387f9dfdSAndroid Build Coastguard Worker
128*387f9dfdSAndroid Build Coastguard Worker# ./memleak -p $(pidof allocs) -s 10 5 3
129*387f9dfdSAndroid Build Coastguard WorkerAttaching to pid 2614, Ctrl+C to quit.
130*387f9dfdSAndroid Build Coastguard Worker[11:16:33] Top 2 stacks with outstanding allocations:
131*387f9dfdSAndroid Build Coastguard Worker        16 bytes in 1 allocations from stack
132*387f9dfdSAndroid Build Coastguard Worker                 main+0x6d [allocs]
133*387f9dfdSAndroid Build Coastguard Worker                 __libc_start_main+0xf0 [libc-2.21.so]
134*387f9dfdSAndroid Build Coastguard Worker
135*387f9dfdSAndroid Build Coastguard Worker[11:16:38] Top 2 stacks with outstanding allocations:
136*387f9dfdSAndroid Build Coastguard Worker        16 bytes in 1 allocations from stack
137*387f9dfdSAndroid Build Coastguard Worker                 main+0x6d [allocs]
138*387f9dfdSAndroid Build Coastguard Worker                 __libc_start_main+0xf0 [libc-2.21.so]
139*387f9dfdSAndroid Build Coastguard Worker
140*387f9dfdSAndroid Build Coastguard Worker[11:16:43] Top 2 stacks with outstanding allocations:
141*387f9dfdSAndroid Build Coastguard Worker        32 bytes in 2 allocations from stack
142*387f9dfdSAndroid Build Coastguard Worker                 main+0x6d [allocs]
143*387f9dfdSAndroid Build Coastguard Worker                 __libc_start_main+0xf0 [libc-2.21.so]
144*387f9dfdSAndroid Build Coastguard Worker
145*387f9dfdSAndroid Build Coastguard WorkerNote that even though the application leaks 16 bytes of memory every second,
146*387f9dfdSAndroid Build Coastguard Workerthe report (printed every 5 seconds) doesn't "see" all the allocations because
147*387f9dfdSAndroid Build Coastguard Workerof the sampling rate applied.
148*387f9dfdSAndroid Build Coastguard Worker
149*387f9dfdSAndroid Build Coastguard WorkerProfiling in memory part is hard to be accurate because of BPF infrastructure.
150*387f9dfdSAndroid Build Coastguard Workermemleak keeps misjudging memory leak on the complicated environment which has
151*387f9dfdSAndroid Build Coastguard Workerthe action of free in hard/soft irq.
152*387f9dfdSAndroid Build Coastguard WorkerAdd workaround to alleviate misjudgments when free is missing:
153*387f9dfdSAndroid Build Coastguard Worker
154*387f9dfdSAndroid Build Coastguard Worker# ./memleak --wa-missing-free
155*387f9dfdSAndroid Build Coastguard WorkerAttaching to kernel allocators, Ctrl+C to quit.
156*387f9dfdSAndroid Build Coastguard Worker...
157*387f9dfdSAndroid Build Coastguard Worker        248 bytes in 4 allocations from stack
158*387f9dfdSAndroid Build Coastguard Worker                 bpf_prog_load [kernel]
159*387f9dfdSAndroid Build Coastguard Worker                 sys_bpf [kernel]
160*387f9dfdSAndroid Build Coastguard Worker
161*387f9dfdSAndroid Build Coastguard Worker        328 bytes in 1 allocations from stack
162*387f9dfdSAndroid Build Coastguard Worker                 perf_mmap [kernel]
163*387f9dfdSAndroid Build Coastguard Worker                 mmap_region [kernel]
164*387f9dfdSAndroid Build Coastguard Worker                 do_mmap [kernel]
165*387f9dfdSAndroid Build Coastguard Worker                 vm_mmap_pgoff [kernel]
166*387f9dfdSAndroid Build Coastguard Worker                 sys_mmap_pgoff [kernel]
167*387f9dfdSAndroid Build Coastguard Worker                 sys_mmap [kernel]
168*387f9dfdSAndroid Build Coastguard Worker
169*387f9dfdSAndroid Build Coastguard Worker
170*387f9dfdSAndroid Build Coastguard WorkerUSAGE message:
171*387f9dfdSAndroid Build Coastguard Worker
172*387f9dfdSAndroid Build Coastguard Worker# ./memleak -h
173*387f9dfdSAndroid Build Coastguard Workerusage: memleak.py [-h] [-p PID] [-t] [-a] [-o OLDER] [-c COMMAND]
174*387f9dfdSAndroid Build Coastguard Worker                  [--combined-only] [--wa-missing-free] [-s SAMPLE_RATE]
175*387f9dfdSAndroid Build Coastguard Worker                  [-T TOP] [-z MIN_SIZE] [-Z MAX_SIZE] [-O OBJ]
176*387f9dfdSAndroid Build Coastguard Worker                  [interval] [count]
177*387f9dfdSAndroid Build Coastguard Worker
178*387f9dfdSAndroid Build Coastguard WorkerTrace outstanding memory allocations that weren't freed.
179*387f9dfdSAndroid Build Coastguard WorkerSupports both user-mode allocations made with libc functions and kernel-mode
180*387f9dfdSAndroid Build Coastguard Workerallocations made with kmalloc/kmem_cache_alloc/get_free_pages and corresponding
181*387f9dfdSAndroid Build Coastguard Workermemory release functions.
182*387f9dfdSAndroid Build Coastguard Worker
183*387f9dfdSAndroid Build Coastguard Workerpositional arguments:
184*387f9dfdSAndroid Build Coastguard Worker  interval              interval in seconds to print outstanding allocations
185*387f9dfdSAndroid Build Coastguard Worker  count                 number of times to print the report before exiting
186*387f9dfdSAndroid Build Coastguard Worker
187*387f9dfdSAndroid Build Coastguard Workeroptional arguments:
188*387f9dfdSAndroid Build Coastguard Worker  -h, --help            show this help message and exit
189*387f9dfdSAndroid Build Coastguard Worker  -p PID, --pid PID     the PID to trace; if not specified, trace kernel
190*387f9dfdSAndroid Build Coastguard Worker                        allocs
191*387f9dfdSAndroid Build Coastguard Worker  -t, --trace           print trace messages for each alloc/free call
192*387f9dfdSAndroid Build Coastguard Worker  -a, --show-allocs     show allocation addresses and sizes as well as call
193*387f9dfdSAndroid Build Coastguard Worker                        stacks
194*387f9dfdSAndroid Build Coastguard Worker  -o OLDER, --older OLDER
195*387f9dfdSAndroid Build Coastguard Worker                        prune allocations younger than this age in
196*387f9dfdSAndroid Build Coastguard Worker                        milliseconds
197*387f9dfdSAndroid Build Coastguard Worker  -c COMMAND, --command COMMAND
198*387f9dfdSAndroid Build Coastguard Worker                        execute and trace the specified command
199*387f9dfdSAndroid Build Coastguard Worker  --combined-only       show combined allocation statistics only
200*387f9dfdSAndroid Build Coastguard Worker  --wa-missing-free     Workaround to alleviate misjudgments when free is
201*387f9dfdSAndroid Build Coastguard Worker                        missing
202*387f9dfdSAndroid Build Coastguard Worker  -s SAMPLE_RATE, --sample-rate SAMPLE_RATE
203*387f9dfdSAndroid Build Coastguard Worker                        sample every N-th allocation to decrease the overhead
204*387f9dfdSAndroid Build Coastguard Worker  -T TOP, --top TOP     display only this many top allocating stacks (by size)
205*387f9dfdSAndroid Build Coastguard Worker  -z MIN_SIZE, --min-size MIN_SIZE
206*387f9dfdSAndroid Build Coastguard Worker                        capture only allocations larger than this size
207*387f9dfdSAndroid Build Coastguard Worker  -Z MAX_SIZE, --max-size MAX_SIZE
208*387f9dfdSAndroid Build Coastguard Worker                        capture only allocations smaller than this size
209*387f9dfdSAndroid Build Coastguard Worker  -O OBJ, --obj OBJ     attach to allocator functions in the specified object
210*387f9dfdSAndroid Build Coastguard Worker
211*387f9dfdSAndroid Build Coastguard WorkerEXAMPLES:
212*387f9dfdSAndroid Build Coastguard Worker
213*387f9dfdSAndroid Build Coastguard Worker./memleak -p $(pidof allocs)
214*387f9dfdSAndroid Build Coastguard Worker        Trace allocations and display a summary of "leaked" (outstanding)
215*387f9dfdSAndroid Build Coastguard Worker        allocations every 5 seconds
216*387f9dfdSAndroid Build Coastguard Worker./memleak -p $(pidof allocs) -t
217*387f9dfdSAndroid Build Coastguard Worker        Trace allocations and display each individual allocator function call
218*387f9dfdSAndroid Build Coastguard Worker./memleak -ap $(pidof allocs) 10
219*387f9dfdSAndroid Build Coastguard Worker        Trace allocations and display allocated addresses, sizes, and stacks
220*387f9dfdSAndroid Build Coastguard Worker        every 10 seconds for outstanding allocations
221*387f9dfdSAndroid Build Coastguard Worker./memleak -c "./allocs"
222*387f9dfdSAndroid Build Coastguard Worker        Run the specified command and trace its allocations
223*387f9dfdSAndroid Build Coastguard Worker./memleak
224*387f9dfdSAndroid Build Coastguard Worker        Trace allocations in kernel mode and display a summary of outstanding
225*387f9dfdSAndroid Build Coastguard Worker        allocations every 5 seconds
226*387f9dfdSAndroid Build Coastguard Worker./memleak -o 60000
227*387f9dfdSAndroid Build Coastguard Worker        Trace allocations in kernel mode and display a summary of outstanding
228*387f9dfdSAndroid Build Coastguard Worker        allocations that are at least one minute (60 seconds) old
229*387f9dfdSAndroid Build Coastguard Worker./memleak -s 5
230*387f9dfdSAndroid Build Coastguard Worker        Trace roughly every 5th allocation, to reduce overhead
231