ndk可以通过在-fsanitize=address
和LOCAL_CFLAGS
中添加LOCAL_LDFLAGS
标志来对任何用它构建的内容启用地址消毒器,这很好。好吧,如果真的成功了就好了。如果添加该标志并尝试构建库,则会出现一堆“未定义符号”错误。通过将-Wl,--unresolved-symbols=ignore
传递给链接器,您可以忽略这些错误,并且构建将成功完成,但是当然,冒险不会就此结束。
然后Google's guide表示您需要一个根设备,在该设备上运行一个脚本,该脚本修改系统分区上的运行时可执行文件,以便加载asan库,然后在运行时加载前面提到的丢失符号链接。我尝试过这种方法,但这种方法的主要问题是它也会在jvm中分析一些东西,从而使它慢下来,以至于应用程序根本不会启动,也不会在jvm中的某个地方崩溃。
我也在模拟器上尝试过新的malloc debug,但它也调试了整个jvm,因此使其不可用。所有这些工具似乎绝对不是针对应用程序开发人员,而是针对那些在android上工作的人。
我迫切需要一种方法来修复我的应用程序中的内存损坏崩溃,而无需在此过程中分析整个虚拟机。如果我把它的库放进apk并加载到jni库之前,asan会工作吗?有没有其他方法来调试这个?人们如何在android上修复这种错误呢?
制作一个“最小包装器可执行文件”并在其他一些具有适当调试工具的操作系统上运行它并不是一个真正的选项,因为jni库的使用方式在很大程度上取决于java部分,即使我制作了一个,我也不能完全确定这个bug是否会重现。
更新:我在oreo模拟器上尝试了asan_device_setup
脚本,因为它在nexus 9和nougat上根本不起作用。日志中充斥着32位进程的链接器错误,这些进程试图加载64位库,然后就冻结了,使其再次可用的唯一方法是刷新工厂映像。为了确保我没有弄糟任何东西,我尝试了几次刷新工厂映像,然后twrp,而不是supersu,然后使用“adbd不安全”应用程序以根用户身份重新启动adb守护程序。所以,我用-writable-system
启动了模拟器并在上面运行了脚本,它成功地完成了。然后我用asan构建了我的应用程序并安装了它,但在启动时它会崩溃。我试过有或没有java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__asan_init_v3" referenced by "/data/...full path to the shared library
,结果是一样的。
最佳答案
如果您发现性能问题如此严重,您可能应该提交错误(http://b.android.com)。我们运行的设备每天都是全自动的,而且比你想象的要好。asan的速度大约慢了2倍,但是用asan运行你的应用应该可以。
debug malloc也一样(我不记得debug malloc的性能含义,但我认为它们比asan不那么严重)。