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