如何调试malloc(堆越界)问题
on init
export LD_PRELOAD libsigchain.so:libudf.so
指的是libudf.so 应该放在最前面,但如果有libsigchain.so的话,就要放在它后面。
case1:
libudf.so:libdirect-coredump.so
case2:
libsigchain.so:libudf.so:libdirect-coredump.so
adb shell setprop persist.libc.debug15.prog system_server
adb shell setprop persist.debug15.config 0x4a003024
libsigchain.so:libudf.so
cat /proc/system_server的PID/maps | grep "malloc debug"
f3540000-f5940000 rw-p 00000000 00:00 0 [anon:malloc debug]
开启mobilelog,和taglog,root后,setprop ro.monkey true,开始monkey测试,复现NE
Android Native进程内存泄露检测
get_malloc_leak_info 就可以使用leak_malloc()获取内存分配情况。
MemoryTrackUtil.cpp 有封装get_malloc_leak_info ,可以在可以的函数调用位置增加
dumpMemoryAddresses 调用从而打印出内存分配信息。
运行时使用:
1.如果system.img中不存在libc_malloc_debug_leak.so,那么把它push到/system/lib中并修改权限
2.setprop libc.debug.malloc 1
3.kill需要检测的进程,使这个property设置后生效
dump出来的文件如以下的格式:
size 262888, dup 1, 0x769a2032, 0x76ed9cce, 0x76ec991a, 0x76f52034, 0x76f62af8,
size 262144, dup 1, 0x769a2032, 0x76ed9cce, 0x76a824d4, 0x76a5e99a, 0x76bf39c2,
size 172036, dup 3, 0x769a2032, 0x76ed9cce, 0x764378c6, 0x7643791e, 0x76414912,
size 172036, dup 3, 0x769a2032, 0x76ed9cce, 0x764378c6, 0x7643791e, 0x76414912,
size代表malloc的内存大小。
dup值代表同一个地方分配的内存次数。对比dump出的不同时间段的文件,如果发现某一条malloc信息的dup越来越大,那么可以怀疑这个地方存在内存泄露。
最后一串字符串表示的是调用的堆栈。这个堆栈需要去减掉栈区间的起始位置,然后才能使用addr2line去查找这个调用堆栈。
举个例子:
size 262888, dup 1, 0x765a2032,
------------------------------------------
765b1000-76688000 r-xp 00000000 b3:05 875 /system/lib/libc.so
那么实际去使用addr2line的stack值应该是 0x765a2032 - 765b1000
在MediaServer中调用这个API就很容易了
Android天然的已经在mediaserver中支持了这个功能。在MediaPlayerService.cpp中已经加入了dumpMemory 这个API。 并且以dumpsys的接口提供给用户使用,所以在对mediaserver相关进程进行dubug的时候只需要如下几步即可:
setprop libc.debug.malloc 1
busybox killall -HUP mediaserver
dumpsys media.player -m
当然,如果需要dump不同时间段的信息,那么只需要写一个shell脚本就可以了。