在AndroidStudio上使用AddressSanitizer
在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=1on 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编译器。
- 开启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)
- 使用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的更多相关文章
- GitLab/Git在AndroidStudio上的使用(转)
1.在AndroidStudio上的配置GitLab 1)首先先将gitlab上的开发项目clone到本地(可以使用命令行或者管理工具,具体操作在GitLab中已经涉及,这里不再赘述),然后导入到An ...
- 一篇文章了解Github和Git教程-AndroidStudio上传Github教程
前言 为了方便保存自己的代码,下班后可以回家继续进行,自己的码农工作,介绍一下Github. 什么是Github呢? 作为一个编程人员,我觉得得了解一下Github吧! 当然,如果你放弃了码农或者技术 ...
- androidstudio上传代码到git上
1.首先通过git --bare init 在服务端创建好了一个git仓库:假设git仓库在服务端的地址为:/user/lyh/project/test.git 2.androidstudio上点击V ...
- Cocos2d-x 3.4在AndroidStudio上编译配置
转载请标明出处:http://www.cnblogs.com/studweijun/p/4320778.html 1.准备好以下文件 1) AndroidStudio: https://dl.goo ...
- Cocos2dx 3.12 在AndroidStudio上编译配置
转载请标明出处:http://www.cnblogs.com/studweijun/p/5805576.html SDK,NDK,ANT的配置请看这里http://www.cnblogs.com/st ...
- 使用AndroidStudio上传忽略文件至SVN Server的解决措施
在同组项目进行共享时,容易把本地的配置文件比如*.iml等文件上传至共享服务器,这样会对队友造成巨大的麻烦,为了解决这个问题,可以使用下面方法解决,下面以上传到服务器的app.iml文件为例. 一.在 ...
- AndroidStudio第一个项目HelloWorld
实验内容 在Android Studio中创建项目 创建并启动Android模拟器 项目的编译和运行 实验要求 在安装好的AndroidStudio上建立第一个工程 创建并启动Android模拟器 编 ...
- 软工实践练习一(个人)----将Androidstudio的项目共享到github
在Androidstudio上使用git插件 将项目共享至github 将 显示共享成功但是出了点问题 项目文件并没有上传至github库中,而是只创建了一个新的库 问题在于我的gitforwindo ...
- Androidstudio 点9图报错的问题
在eclipse上.9图能够正常使用,但是到了Androidstudio上就报错无法引用,提示找不到.9图的问题. 解决方案: Androidstudio对.9图进行了更严格的定义, 1. 如果一 ...
随机推荐
- 基于LinkedList实现桶排序
需要考虑以下问题: 1.桶的大小,这里我们可以根据输入的元素的个数来确定桶的大小. 2.怎么样确定当前元素进入哪一个桶,这里我们使用到的是通过一个哈希函数来进行计算. int index = (ele ...
- 【DFS】数独游戏
DFS(深度优先搜索): 深度优先搜索算法(英语:Depth-First-Search,简称DFS)是一种用于遍历或搜索树或图的算法. 沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所在 ...
- [Swift]LeetCode263. 丑数 | Ugly Number
Write a program to check whether a given number is an ugly number. Ugly numbers are positive numbers ...
- [Swift]LeetCode318. 最大单词长度乘积 | Maximum Product of Word Lengths
Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the tw ...
- Python文本数据互相转换(pandas and win32com)
(工作之后,就让自己的身心都去休息吧) 今天介绍一下文本数据的提取和转换,这里主要实例的转换为excel文件(.xlsx)转换world文件(.doc/docx),同时需要使用win32api,同py ...
- Oracle synonym 同义词
Oracle synonym 同义词 1.Oracle synonym 同义词是数据库当前用户通过给另外一个用户的对象创建一个别名,然后可以通过对别名进行查询和操作,等价于直接操作该数据库对象. 2. ...
- [原创]利用Browser协议探测内网主机操作系统版本(无需端口无视防火墙)
利用Browser协议可获取机器IP.MAC.机器名.操作系统.域,如图 浏览 在SMB协议中,计算机为了访问网络资源,就需要了解网络上存在的资源列表(例如在Windows下使用网络邻居查看可以访问的 ...
- linux 关机命令shutdown
linux系统,正确的关机很重要,因为linux是多任.多用户系统,在后台可能同时有很多人在主机上面工作.不正确的挂机可能会导致数据中断. 1.关机前的操作(可以不进行) 可以使用who命令查看系统有 ...
- RabbitMQ学习笔记(五) Topic
更多的问题 Direct Exchange帮助我们解决了分类发布与订阅消息的问题,但是Direct Exchange的问题是,它所使用的routingKey是一个简单字符串,这决定了它只能按照一个条件 ...
- java~spring-ioc的使用
spring-ioc的使用 IOC容器在很多框架里都在使用,而在spring里它被应用的最大广泛,在框架层面 上,很多功能都使用了ioc技术,下面我们看一下ioc的使用方法. 把服务注册到ioc容器 ...