Android平台开发C++程序的有效工具

本文介绍了在Android平台上进行C++程序开发时,如何利用CallStack类打印调用栈以提升调试效率,以及如何通过内存泄漏检测工具,如valgrind和内存泄漏检测动态库,进行内存泄漏检测。详细步骤包括调用栈的获取、内存泄漏文件的生成和分析,以及利用addr2func工具转换函数地址为函数原型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、打印调用栈

程序开发和调试很多时候都离不开调用栈的打印,尤其是调试复杂的程序,比如异步程序时或基于回调的程序时,看代码还是挺费时间的,效率还不高。

这时打印一下调用栈往往事半功倍。

在linux上打印调用栈有backtrace, backtrace_symbols, backtrace_symbols_fd等函数可以用,在shell中man backtrace就可以看到相关解释。

在android中则有 /​,用法简单: android::CallStack cs; cs.update(2); cs.dump();

update函数会调用_Unwind_Backtrace来获得调用栈,这时调用栈只是一些函数地址。

只有调用dump时,才会将这些函数地址转换成可读性比较好的函数名,文件名,甚至行号等。

dump先尝试用dladdr来将函数地址转换成函数名(在c++中是被mangling过的),如果成功,则对其进行demangling,得到函数的原型。

如果dladdr失败,则会读取进程的maps文件,解析该文件,得到进程中被加载的动态库的地址范围,然后根据要转换的函数地址,找到对应的动态库,将该动态库的路径打印出来。

二、检测内存泄漏

内存泄漏的检测如果没有工具的支持估计只能靠阅读代码和猜了。

linux上有valgrind,已经比较成熟了,它在android上也同样有效,用NDK将其交叉编译之后就可以使用了。

本人在项目中使用过的另外一种方法是,用android sdk中的bionic里面提供的memory leak检测工具。

这两个文件中包含了我们所需要的工具。


具体用法是:

(1) 将头文件dumpnativeheap.h 加入到源文件中。

(2) 在合适的位置调用dumpNativeHeapToFile(char *pFile),这个函数会将当前时刻堆上的内存分配情况以及进程的maps保存到你指定的文件中。

这里所说的合适的位置需要开发人员自己定,比如你想测试一个播放引擎有没有内存泄漏,则可以在播放之前,调用一次,在播放结束之后,再调用一次。这样就会得到两个文件。

(3)交叉编译你的程序,并推送到android设备上。

(4)  重启系统,使其使用libc_malloc_debug_leak.so,而不是libc.so。

adb shell setprop libc.debug.malloc 1   =》 将malloc库的debug level设置成memory leak detection

adb shell stop

adb shell start

(5)在android 上运行你的程序,如(2)所说,你将得到两个文件。

(6)将这两个文件做diff,得到一个diff文件。

(7)将第二个文件的maps部分拷贝到一个新文件中。这里我们基本上可以认为两个文件的maps是相同的。比如我们要测试播放引擎的内存泄漏,我们在dump的时候一般是在所需的动态库都加载完之后哦才dump,所以两个maps应该是相同的。

(8)把你的可执行程序或动态库(注意,这里应该都是debug版本,即带有符号表信息的版本)拷贝到android SDK的target symbol 目录下。

比如android/4.0.0_sdk/out/target/product/generic/symbols/data/memleaktest, 这里的/data/memleaktest和android设备上我们的可执行程序的路径一致。

(9)执行网上的脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值