在AndroidStudio上使用AddressSanitizer

AddressSanitizer是Google主导的一个开源内存问题检测工具。现在也开始支持Android平台,且受Google推荐来替代之前的Valgrind。目前AddressSanitizer能够发现如下问题:

  • Out-of-bounds accesses to heap, stack and globals
  • Use-after-free
  • Use-after-return (runtime flag ASAN_OPTIONS=detect_stack_use_after_return=1)
  • Use-after-scope (clang flag -fsanitize-address-use-after-scope)
  • Double-free, invalid free
  • Memory leaks (experimental)

其中,值得一提的是Memory leaks,现在还是experiment,准确的说,现在还只支持Linux平台,并不支持Android。所以,想写一个内存泄露来检验AddressSanitizer是否生效就要注意了,就像本人一样,其实AddressSanitizer都已经正常运行了,然后一直没有检测出来Memory leaks就以为没有生效,导致浪费了很多时间。

For more information on leak detector in AddressSanitizer, see LeakSanitizer. The leak detection is turned on by default on Linux, and can be enabled using ASAN_OPTIONS=detect_leaks=1 on OS X; however, it is not yet supported on other platforms.

也许有人会说,Android不也是Linux嘛。这个的话,从它的Supported Platforms:

  • Linux i386/x86_64 (tested on Ubuntu 12.04)
  • OS X 10.7 - 10.11 (i386/x86_64)
  • iOS Simulator
  • Android ARM
  • NetBSD i386/x86_64
  • FreeBSD i386/x86_64 (tested on FreeBSD 11-current)

就可以看出来,Linux和Android是不同的。而且这里还注明了必须ARM,也就是说如果用非ARM的Android设备可能就不支持。个人认为这和AddressSanitizer的实现机制有关。因为它是通过重写比如malloc之类的函数,构造shadow Memory来实现的检测。而这些函数可能都是汇编语言写的,所以不同的CPU硬件就需要不同的实现版本。

AS中的应用

编译指令

其实很简单,就两点,开启AddressSanitizer标志和使用clang编译器。

  1. 开启AddressSanitizer标志:在CMakeLists.txt中添加如下语句:
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -fsanitize=address -fno-omit-frame-pointer")
SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -fsanitize=address -fno-omit-frame-pointer")
SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
SET (CMAKE_ANDROID_ARM_MODE ARM)
  1. 使用clang编译:在build.gradle的cmake模块下面添加:
arguments "-DANDROID_TOOLCHAIN=clang"
在设备中安装ASAN

要点:

  • 设备需要root
  • 运行ndk中的asan_device_setup脚本

关于asan_device_setup脚本,在AS自带的ndk-bundle中,其脚本路径为ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/7.0.2/bin/asan_device_setup,而如果是自己单独安装的NDK,那么其路径为NDKROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/asan_device_setup。如果脚本执行成功,那么设备就会自动重启,在本人实践中,最后部分信息如下:

>> Pushing files to the device
Installing /system/lib/libclang_rt.asan-arm-android.so 644
[100%] /system/lib/libclang_rt.asan-arm-android.so
Installing /system/lib64/libclang_rt.asan-aarch64-android.so 644
[100%] /system/lib64/libclang_rt.asan-aarch64-android.so
Installing /system/bin/app_process32 755 u:object_r:zygote_exec:s0
[100%] /system/bin/app_process32
Installing /system/bin/app_process32.real 755 u:object_r:zygote_exec:s0
[100%] /system/bin/app_process32.real
Installing /system/bin/app_process64 755 u:object_r:zygote_exec:s0
[100%] /system/bin/app_process64
Installing /system/bin/app_process64.real 755 u:object_r:zygote_exec:s0
[100%] /system/bin/app_process64.real
Installing /system/bin/asanwrapper 755
[100%] /system/bin/asanwrapper
Installing /system/bin/asanwrapper64 755
[100%] /system/bin/asanwrapper64
>> Restarting shell (asynchronous)
>> Please wait until the device restarts
测试

有了前面两步,就可以实验了,其实还是很简单的。

使用AS新建一个C++支持的默认Android项目,然后修改其native函数如下:

extern "C" JNIEXPORT jstring
JNICALL
Java_com_example_willhua_asantest_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++"; int *ptr = (int*)malloc(sizeof(int) * 3);
ptr[4] = 6; return env->NewStringUTF(hello.c_str());
}

然后在注意Build Variant为debug,点击启动就OK啦。然后在log中可以看到检测到了heap-buffer-overflow:

参考

clang: AddressSanitizer

Android Native内存检测

内存检测工具

AddressSanitizerOnAndroid

在AndroidStudio上使用AddressSanitizer的更多相关文章

  1. GitLab/Git在AndroidStudio上的使用(转)

    1.在AndroidStudio上的配置GitLab 1)首先先将gitlab上的开发项目clone到本地(可以使用命令行或者管理工具,具体操作在GitLab中已经涉及,这里不再赘述),然后导入到An ...

  2. 一篇文章了解Github和Git教程-AndroidStudio上传Github教程

    前言 为了方便保存自己的代码,下班后可以回家继续进行,自己的码农工作,介绍一下Github. 什么是Github呢? 作为一个编程人员,我觉得得了解一下Github吧! 当然,如果你放弃了码农或者技术 ...

  3. androidstudio上传代码到git上

    1.首先通过git --bare init 在服务端创建好了一个git仓库:假设git仓库在服务端的地址为:/user/lyh/project/test.git 2.androidstudio上点击V ...

  4. Cocos2d-x 3.4在AndroidStudio上编译配置

    转载请标明出处:http://www.cnblogs.com/studweijun/p/4320778.html 1.准备好以下文件 1) AndroidStudio:  https://dl.goo ...

  5. Cocos2dx 3.12 在AndroidStudio上编译配置

    转载请标明出处:http://www.cnblogs.com/studweijun/p/5805576.html SDK,NDK,ANT的配置请看这里http://www.cnblogs.com/st ...

  6. 使用AndroidStudio上传忽略文件至SVN Server的解决措施

    在同组项目进行共享时,容易把本地的配置文件比如*.iml等文件上传至共享服务器,这样会对队友造成巨大的麻烦,为了解决这个问题,可以使用下面方法解决,下面以上传到服务器的app.iml文件为例. 一.在 ...

  7. AndroidStudio第一个项目HelloWorld

    实验内容 在Android Studio中创建项目 创建并启动Android模拟器 项目的编译和运行 实验要求 在安装好的AndroidStudio上建立第一个工程 创建并启动Android模拟器 编 ...

  8. 软工实践练习一(个人)----将Androidstudio的项目共享到github

    在Androidstudio上使用git插件 将项目共享至github 将 显示共享成功但是出了点问题 项目文件并没有上传至github库中,而是只创建了一个新的库 问题在于我的gitforwindo ...

  9. Androidstudio 点9图报错的问题

    在eclipse上.9图能够正常使用,但是到了Androidstudio上就报错无法引用,提示找不到.9图的问题.   解决方案: Androidstudio对.9图进行了更严格的定义, 1. 如果一 ...

随机推荐

  1. [Swift]LeetCode139. 单词拆分 | Word Break

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  2. [Swift]LeetCode593. 有效的正方形 | Valid Square

    Given the coordinates of four points in 2D space, return whether the four points could construct a s ...

  3. 解决Xftp连接不上Linux虚拟机问题。

    首先 打开cmd窗口 ping一下 虚拟机的ip 这样证明是可以连接的,如果不可以就是你ip地址这块的问题. 可以之后打开Xftp新建 ,把默认的FTP改成SFTP.

  4. Java学习目录(持续更新中)

  5. 使用Autofac动态注入启动Api服务

    Autofac Autofac(https://autofac.org/)是一款.NET的IOC组件,它可以和Owin, Web Api, ASP.NET MVC, .NET Core完美结合,帮助开 ...

  6. [linux]孤儿进程与僵尸进程

    转载自:http://www.cnblogs.com/Anker/p/3271773.html 一.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两 ...

  7. 带着新人学springboot的应用13(springboot+热部署)

    spring cloud我想做成一个系列,所以spring cloud+eureka后面会慢慢说到的,有兴趣的小伙伴可以关注后续! 这一节就简单说说springboot的热部署了(我一直想不通为什么叫 ...

  8. Lambda in Java VS in C#

    核心+变化 “凡是钱能解决的问题,就不是大问题.有很多问题是钱无法解决的,比如生老病死,比如不再相爱.”,看过<蜗居>的朋友一眼就能认出来.虽然这部电视剧讲的是chugui,但是毫无违和感 ...

  9. 微服务浪潮中,程序猿如何让自己 Be Cloud Native

    前言 CNCF 与 Cloud Native 这两个技术词汇最近频频走进了程序员的视野,一切和他能搭上边的软件意味着标准.开放.时尚,也更能俘获技术哥哥们的心:这篇文章不想去带大家重温这个词汇后面的软 ...

  10. 说说不知道的Golang中参数传递

    本文由云+社区发表 导言 几乎每一个C++开发人员,都被面试过有关于函数参数是值传递还是引用传递的问题,其实不止于C++,任何一个语言中,我们都需要关心函数在参数传递时的行为.在golang中存在着m ...