如何调试malloc(堆越界)问题

时间:2022-11-21 10:42:39

如何调试malloc(堆越界)问题

[DESCRIPTION]


有一类NE比较特殊,就是堆引起的异常(调用malloc申请的内存后使用不当引起的异常):
1. 申请后多次释放 (double free)
2. 释放后又去使用 (used after free)
3. 使用越界 (比如申请了50节内存,结果在使用时多用了8字节的内存,这样就把后面的内存的内容踩坏,引起堆结构 异常)
4. 释放时传给free()的地址不是malloc()申请的地址,比如:p = malloc(10); free(p + 5);
5. 内存泄露:申请内存后,忘记释放或某些代码路径没有释放。此类问题的调试请参考FAQ05872 如何用DDMS分析 native memory leak 那如何去识别这类NE呢?
如果从调用栈(main log/aee_exp里的db里的_exp_detail.txt或/data/tombstone下的文件里可能存在)查看到#0~3帧有
malloc/free这些函数,那么认为是malloc问题(也就是执行到这些函数时发生了异常):
如何调试malloc(堆越界)问题

4.22tp-1.png (123 KB, 下载次数: 0 )

下载附件  保存到相册

2016-4-22 10:52 上传



[SOLUTION]


如何调试此类问题呢?方法是每次调用malloc时记录调用栈并做相关的安全检查(在头尾做特定的标记),调用free时检 查标记是否被踩坏,如果是则报错
android本身有集成集中调试机制,代码在bionic/libc/bionic/malloc_debug_common.c/h/cpp,可以通过属性控制:
setprop libc.debug.malloc 0: 这是默认的等级,仅作最基本的判断
setprop libc.debug.malloc 1: 这会在malloc记录调用栈,用于分析内存泄露
setprop libc.debug.malloc 5: 在申请后会填充固定的pattern,用于检查是否越界访问
setprop libc.debug.malloc 10: 增加foot/head头,记录调用栈
setprop persist.libc.debug.malloc 15: MTK增加的调试等级,会记录调用栈,额外存在其他地方以免被踩坏
setprop persist.libc.debug.malloc 16: MTK增加的调试等级,包含debug15,并且还支持对dvm堆调试
setprop libc.debug.malloc 20: 模拟器使用
以后如果遇到此类问题,请按以下配置重新复现即可(请使用eng或userdebug版本):
KK及以前版本:(如果是JB2.MP版本请先打上patch:ALPS00448232)
开机后用adb输入:
adb shell setprop persist.libc.debug.malloc 15
adb shell setprop persist.debug15.prog xxxx (xxxx为应用程序,比如JAVA程序都是app_process,不清楚则填ALL)
adb shell setprop persist.debug15.config 0x24002020 (只有JB5及之后才支持,不是这些版本的不用设置这个属性
)
adb reboot
L及之后版本:在
vendor/mediatek/proprietary/external/aee/config_external/init.aee.customer.rc添加:
on init
export LD_PRELOAD libsigchain.so:libudf.so
重新打包bootimage并下载, 开机后用adb输入:
adb shell setprop persist.libc.debug.malloc 15
adb shell setprop persist.libc.debug15.prog xxxx (xxxx为应用程序,比如java程序都是
app_process,不清楚则填ALL)
adb shell setprop persist.debug15.config 0x2a003024
adb reboot
这时会重启手机,再次开机后就进入malloc/free的调试方式,此时overhead会比较重,可能会有一些不预期的anr(出
现ANR时请点击等待),但不影响测试。
测试前,请注意保留out/target/product/$project/symbols目录
问题复现之后,请用GAT(和flashtool一起释放,并且在DCC上有说明文档)的bugreport功能抓取异常信息并打包,提 交e-service并提供打包后的文件。
--------------------------------------------------------------------------------------------------------
---------------------
如果一定要在user版本使用malloc debug功能,请:
1. 获取adb shell的root权限,请查看[FAQ06317] 如何永久性开启adb的root权限
2. 请编译eng版本的libc.so和libc_malloc_debug_mtk.so(放在
vendor/mediatek/$proj/artifacts/out/target/product/$proj/system/lib目录下,如果没有请提e-service申请
),用adb push到/system/lib目录下
3. 如果是GB3版本,在编译eng版本的libc.so之前,注释掉bionic/libc/malloc_debug_common.c以下代码再编译:
if (__system_property_get("ro.build.type", env)) {
if (strncmp(env, "eng", 3))
debug_level = 0;
}
4. 如果是JB3/GB3以后的版本,请设置
adb shell aee -d coreon
5. 然后在按照eng版本连adb设置persist.libc.debug.malloc/persist.debug15.prog/persist.debug15.config属性 ,重开机复现即可。