Detect Memory Leak with gperftools

1 minute read

Build libtcmalloc

arm

git clone https://github.com/gperftools/gperftools
git checkout gperftools-2.15

. /opt/poky/4.0.15/environment-setup-cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi
./autogen.sh
./configure --host=arm-poky-linux-gnueabi
make
file .libs/libtcmalloc.so.4.5.16
.libs/libtcmalloc.so.4.5.16: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=28d08ac24d1101ddf53aa1a1c5e20c6311c2c5b5, with debug_info, not stripped

scp .libs/libtcmalloc.so root@192.168.1.80:/lib/

arm64

. /opt/poky/4.0.15/environment-setup-cortexa53-crypto-poky-linux
./autogen.sh
./configure --host=aarch64-poky-linux
make
file .libs/libtcmalloc.so.4.5.16
file .libs/libtcmalloc.so.4.5.16: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=cfafed6e1920f498dcf9807accca32fbf3321dba, with debug_info, not stripped
scp .libs/libtcmalloc.so root@192.168.1.81:/usr/lib/

Memory Leak with Example

cat -n memleak.c

#include <stdio.h>
#include <stdlib.h>

void bar(int bytes)
{
    for (unsigned int j = 0; j < 2; j++)
        malloc(bytes);
}

void foo()
{
    calloc(16, 16);
    bar(50);
}

int main(void)
{
    foo();

    exit(EXIT_SUCCESS);
}
# arm
arm-poky-linux-gnueabi-gcc -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -fstack-protector-strong --sysroot=/opt/poky/4.0.15/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi -o memleak memleak.c
# arm64
aarch64-poky-linux-gcc --sysroot=/opt/poky/4.0.15.arm64/sysroots/cortexa53-crypto-poky-linux -g -o memleak memleak.c

scp memleak root@192.168.1.80:/tmp/
scp /opt/poky/4.0.15/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/lib/libstdc++.so.6 root@192.168.1.80:/usr/lib/

export LD_PRELOAD="/lib/libtcmalloc.so"
env HEAPCHECK=normal /tmp/memleak
root@raspberrypi3:~# env HEAPCHECK=normal /tmp/memleak
No live heap object at 0x76f03250 to ignore
WARNING: Perftools heap leak checker is active -- Performance may suffer
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 356 bytes in 3 objects
The 1 largest leaks:
*** WARNING: Cannot convert addresses to symbols in output below.
*** Reason: Cannot find 'pprof' (is PPROF_PATH set correctly?)
*** If you cannot fix this, try running pprof directly.
Leak of 356 bytes in 3 objects allocated from:


If the preceding stack traces are not enough to find the leaks, try running THIS shell command:

pprof /tmp/memleak "/tmp/memleak.290._main_-end.heap" --inuse_objects --lines --heapcheck  --edgefraction=1e-10 --nodefraction=1e-10 --gv

If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it might help find leaks more rep
Exiting with error code (instead of crashing) because of whole-program memory leaks