How to Trace the Low-Level Malloc

Document created by Xinyu (eric) Chen Employee on Oct 11, 2012Last modified by Jodi Paul on Mar 14, 2013
Version 6Show Document
  • View in full screen mode

Trace the malloc and expose violate access to freed memory

 

 

Introduction

 

Libc has a malloc debug framework for difference debugger. Each debugger takes as a libraries, and override the default malloc/free/calloc/realloc/, hooked before calling the real functions.

 

NOTE: This tip assume that you are working with an eng or userdebug build of the platform, not on a production device.

 

Trace the low level malloc/free in bionic

 

Bionic has a malloc debugger called leak debugger, which can record all the malloc/free in low level. And developers can use ddms on host to check each block of memory on heap by malloc. And ddms support convert caller function address to name conver. That makes easy for us to check which component, which function allocated for how many memories.

You can turn on memory tracking with debug level 1:

$ adb shell setprop libc.debug.malloc 1

$ adb shell stop

$ adb shell start

 

You need to restart the runtime so that zygote and all processes launched from it are restarted with the property set. Now all Dalvik processes have memory tracking turned on. You can look at these with DDMS, but first you need to turn on its native memory UI:

  • Open ~/.android/ddms.cfg
  • Add a line "native=true"

 

Upon relaunching DDMS and selecting a process, you can switch to the new native allocation tab and populate it with a list of allocations. This is especially useful for debugging memory leaks.

NOTE: to solve the module symbols, please export two env on HOST:

$ export PATH=$PATH:<android src>/prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin

$ export ANDROID_PRODUCT_OUT=<android src>/out/target/product/<platform>

Expose the memory access to freed area

 

In this release he Electric Fence 2.2.0 has been ported to Android. it's also a memory debugger tool as above leak debugger.

It helps you detect two common programming bugs: software that overruns the boundaries of a malloc() memory allocation, and software that touches a memory allocation that has been released by free(). It will dump the call stack and mmap of the process, if the malloc/free is not called with correct parameters. It will also make a segment fault, when applications want to access the address which is freed.

The usage of efence is almost same as above, which we define it's debug level to 15:

$ adb shell setprop libc.debug.malloc 15

 

After setting this property, you can run your applications, and if there's any memory leakage, logcat will show information.

 

Example:

Access the memory, which has been freed already:

root@android:/data # setprop libc.debug.malloc 15

I/libc    ( 4136): setprop using MALLOC_DEBUG = 1 (leak checker)

root@android:/data # ./memtest

I/libc    ( 4138): ./memtest using MALLOC_DEBUG = 15 (efence)

F/libc    ( 4138): Fatal signal 11 (SIGSEGV) at 0x4015bff4 (code=2)

I/DEBUG  ( 3856): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

I/DEBUG  ( 3856): Build fingerprint: 'freescale/sabresd_6dq/sabresd_6dq:4.0.4/R13.5-rc1/eng.b03824.20120711.11133

8:eng/test-keys'

I/DEBUG  ( 3856): pid: 4138, tid: 4138  >>> ./memtest <<<

I/DEBUG  ( 3856): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 4015bff4

I/DEBUG  ( 3856):  r0 00000000  r1 00000002  r2 40151c6c  r3 00000000

I/DEBUG  ( 3856):  r4 4015bff4  r5 bec75a54  r6 00000001  r7 bec75a5c

I/DEBUG  ( 3856):  r8 00000000  r9 00000000  10 00000000  fp 00000000

I/DEBUG  ( 3856):  ip 00000000  sp bec75a20  lr 40133f8f  pc 0000a554  cpsr 60000010

I/DEBUG  ( 3856):  d0  203f810033915fe5  d1  0000000000000000

I/DEBUG  ( 3856):  d2  0000000000000000  d3  0000000000000000

I/DEBUG  ( 3856):  d4  0000000000000000  d5  0000000000000000

I/DEBUG  ( 3856):  d6  0000000000000000  d7  204cb48d00000000

I/DEBUG  ( 3856):  d8  0000000000000000  d9  0000000000000000

I/DEBUG  ( 3856):  d10 0000000000000000  d11 0000000000000000

I/DEBUG  ( 3856):  d12 0000000000000000  d13 0000000000000000

I/DEBUG  ( 3856):  d14 0000000000000000  d15 0000000000000000

I/DEBUG  ( 3856):  d16 41c0265a46a47ae1  d17 3f50624dd2f1a9fc

I/DEBUG  ( 3856):  d18 41c9c8aff2800000  d19 0000000000000000

I/DEBUG  ( 3856):  d20 0000000000000000  d21 0000000000000000

I/DEBUG  ( 3856):  d22 0000000000000000  d23 0000000000000000

I/DEBUG  ( 3856):  d24 0000000000000000  d25 0000000000000000

I/DEBUG  ( 3856):  d26 0000000000000000  d27 0000000000000000

I/DEBUG  ( 3856):  d28 0000000000000000  d29 0000000000000000

I/DEBUG  ( 3856):  d30 0000000000000000  d31 0000000000000000

I/DEBUG  ( 3856):  scr 00000010

I/DEBUG  ( 3856):

I/DEBUG  ( 3856):          #00  pc 0000a554  /data/memtest

I/DEBUG  ( 3856):          #01  pc 00016834  /system/lib/libc.so (__libc_init)

I/DEBUG  ( 3856):

I/DEBUG  ( 3856): code around pc:

I/DEBUG  ( 3856): 0000a534 e3a0000a ebfff8d1 e3a01001 e1a00004  ................

I/DEBUG  ( 3856): 0000a544 e5c4100a ebfff8d9 e3560001 e3a03000  ..........V..0..

I/DEBUG  ( 3856): 0000a554 e5c43000 0a000064 e59f21f0 e2857004  .0..d....!...p..

I/DEBUG  ( 3856): 0000a564 e5954004 e08f1002 e1a00004 ebfff8c0  .@..............

I/DEBUG  ( 3856): 0000a574 e3500000 0a00003f e59fc1d4 e1a00004  ..P.?...........

I/DEBUG  ( 3856):

I/DEBUG  ( 3856): code around lr:

I/DEBUG  ( 3856): 40133f6c 68200701 0001f020 454e1046 2e00d018  .. h ...F.NE....

I/DEBUG  ( 3856): 40133f7c 2102da01 1c81e000 43394338 f7eb4622  ...!....8C9C"F..

I/DEBUG  ( 3856): 40133f8c 4605ed56 d1ec2800 da062e00 0101f008  V..F.(..........

I/DEBUG  ( 3856): 40133f9c f06f4620 f7ea4200 4628e8d4 87f0e8bd  Fo..B....(F....

I/DEBUG  ( 3856): 40133fac eff0f7e9 6003234b 30fff04f bf00e7f6  ....K#.`O..0....

I/DEBUG  ( 3856):

I/DEBUG  ( 3856): memory map around addr 4015bff4:

I/DEBUG  ( 3856): 40150000-4015a000

I/DEBUG  ( 3856): 4015a000-4015d000

I/DEBUG  ( 3856): 4015d000-4015e000

I/DEBUG  ( 3856):

I/DEBUG  ( 3856): stack:

I/DEBUG  ( 3856):    bec759e0  00000000

I/DEBUG  ( 3856):    bec759e4  00000000

I/DEBUG  ( 3856):    bec759e8  00000000

I/DEBUG  ( 3856):    bec759ec  4012090f  /system/lib/libefence.so

I/DEBUG  ( 3856):    bec759f0  4015a014

I/DEBUG  ( 3856):    bec759f4  00002000

I/DEBUG  ( 3856):    bec759f8  00000004

I/DEBUG  ( 3856):    bec759fc  40120df1  /system/lib/libefence.so

I/DEBUG  ( 3856):    bec75a00  4015bff4

I/DEBUG  ( 3856):    bec75a04  bec75a54  [stack]

I/DEBUG  ( 3856):    bec75a08  00000001

I/DEBUG  ( 3856):    bec75a0c  bec75a5c  [stack]

I/DEBUG  ( 3856):    bec75a10  00000000

I/DEBUG  ( 3856):    bec75a14  400d9167  /system/lib/libc.so

I/DEBUG  ( 3856):    bec75a18  df0027ad

I/DEBUG  ( 3856):    bec75a1c  00000000

I/DEBUG  ( 3856): #00 bec75a20  00008924  /data/memtest

I/DEBUG  ( 3856):    bec75a24  bec75a54  [stack]

I/DEBUG  ( 3856):    bec75a28  00000001

I/DEBUG  ( 3856):    bec75a2c  bec75a5c  [stack]

I/DEBUG  ( 3856):    bec75a30  00000000

I/DEBUG  ( 3856):    bec75a34  400d9837  /system/lib/libc.so

I/DEBUG  ( 3856): #01 bec75a38  00000000

I/DEBUG  ( 3856):    bec75a3c  00000000

I/DEBUG  ( 3856):    bec75a40  00000000

I/DEBUG  ( 3856):    bec75a44  00000000

I/DEBUG  ( 3856):    bec75a48  00000000

I/DEBUG  ( 3856):    bec75a4c  b00046ef  /system/bin/linker

I/DEBUG  ( 3856):    bec75a50  00000001

I/DEBUG  ( 3856):    bec75a54  bec75b79  [stack]

I/DEBUG  ( 3856):    bec75a58  00000000

I/DEBUG  ( 3856):    bec75a5c  bec75b83  [stack]

I/DEBUG  ( 3856):    bec75a60  bec75b8f  [stack]

I/DEBUG  ( 3856):    bec75a64  bec75ba2  [stack]

I/DEBUG  ( 3856):    bec75a68  bec75bc5  [stack]

I/DEBUG  ( 3856):    bec75a6c  bec75bde  [stack]

I/DEBUG  ( 3856):    bec75a70  bec75c08  [stack]

I/DEBUG  ( 3856):    bec75a74  bec75c20  [stack]

I/DEBUG  ( 3856):    bec75a78  bec75c57  [stack]

I/DEBUG  ( 3856):    bec75a7c  bec75c61  [stack]

I/BootReceiver( 3551): Copying /data/tombstones/tombstone_00 to DropBox (SYSTEM_TOMBSTONE)

D/dalvikvm( 3551): GC_CONCURRENT freed 398K, 10% free 8805K/9735K, paused 3ms+5ms

[2] + Segmentation fault  ./memtest

Attachments

    Outcomes