前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >android native内存检测方案(二)

android native内存检测方案(二)

作者头像
用户1263308
发布2018-02-02 10:41:04
4.4K0
发布2018-02-02 10:41:04
举报
文章被收录于专栏:代码GG之家代码GG之家

android native 代码内存泄露 定位方案(一)

什么是 AddressSanitizer

clang 是一个 C、C++、Objective-C 编程语言的编译器前端。它采用 了底层虚拟机作为其后端。它的目标是提供一个 GNU 编译器套装 (GCC)的替代品, 作者是克里斯·拉特纳,在苹果公司的赞助下进 行开发。 AddressSanitizer 是 clang 中的一个内存错误检测器,它可以检测到 以下问题: Out-of-bounds accesses to heap, stack and globals Use-after-free Use-after-return (to some extent) Double-free, invalid free Memory leaks (experimental) 使 用 clang 编 译 代 码 时 用 -fsanitize=address 就 能 打 开 AddressSanitizer 工具,为了在检测到内存错误时打印出您的程序调 用栈,需要在编译时加上选项 -fno-omit-frame-pointer 选项,同时为 了得出更清晰的调用栈信息,请用-O1 选项编译程序。

sanitizer 例子

我们编写一个 android.mk 文件,内容为: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) #优化,加入 AddressSanitizer 功能 LOCAL_CFLAGS := -std=c11 -Wall -Werror -O0 -fsanitize=address -fno-omit-frame-pointer LOCAL_SRC_FILES:= sanitizer-status.c LOCAL_MODULE:= sanitizer-status LOCAL_MODULE_TAGS := debug #这三行是后面的 UndefinedBehaviorSanitizer 要加的参数 LOCAL_CLANG := true LOCAL_SANITIZE := alignment bounds null unreachable integer LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer #加入需要的库 LOCAL_SHARED_LIBRARIES += libclang_rt.asan-arm-android include $(BUILD_EXECUTABLE) 其中更多的参数为:

-fsanitize=address: AddressSanitizer, a memory error
detector.
-fsanitize=thread: ThreadSanitizer, a data race detector.
-fsanitize=memory:MemorySanitizer,a detector of uninitialized reads. Requires instrumentation of all program code.
-fsanitize=undefined: UndefinedBehaviorSanitizer, a fast
and compatible undefined behavior checker.
-fsanitize=dataflow: DataFlowSanitizer, a general data flow
analysis.
-fsanitize=cfi: control flow integrity checks. Requires -flto.
-fsanitize=safe-stack:safe stack protection against stack-based memory corruption errors.

更加完整的,参考: http://clang.llvm.org/docs/UsersManual.html 官方文档.

添加c代码

sanitizer-status.c 内容为:
#include <stdlib.h>
int main() {
char *x = (char*)malloc(10 * sizeof(char*));
free(x);
return x[5];
}
这里使用了已经释放的内存.
mm 编译出来 bin 文件,我们来继续操作.
官方的完整代码如下:
https://github.com/google/sanitizers

检测效果

我们将 libclang_rt.asan-arm-android.so

放入手机里面 adb push 'prebuilts/clang/host/linux-x86/clang-2690385/lib64/ clang/3.8/lib/linux/libclang_rt.asan-arm-android.so' /system/lib 将此 bin 放入手机 adb push /system/bin/sanitizer-status /system/bin/ 运行此 sanitizer-status,出现最终效果,检测出来当前有使 用了释放的内存.

完整的检测出来内存泄漏,可以去细看此图。打印出来堆栈,以及内存图。

介绍

/docs/source.android.com/src/devices/tech/debug 里 面 , 有 个 asan.jd 我们使用网页打开 主要介绍了检测都可以完成哪些目标  Building executables with AddressSanitizer  Building shared libraries with AddressSanitizer  Symbolization(测试没效果,没有找到 bin 文件)  AddressSanitizer in the apps  SANITIZE_TARGET 更多内容,我们直接去文档阅读即可.

UndefinedBehaviorSanitizer

UndefinedBehaviorSanitizer 说白了也是 clang 的一种检测方式,检测代码中未初始化, 未赋值等等一系列的错误使用. #这三行是后面的 UndefinedBehaviorSanitizer 要加的参数 LOCAL_CLANG := true LOCAL_SANITIZE := alignment bounds null unreachable integer LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer 在需要的地方,加入上面的几行,则可以使用此检测方案.

Kernel Address Sanitizer

参考文档 https://www.ibm.com/developerworks/cn/linux/1608_tengr_kasan/index.html

可以发现, 我们当前的 kernel 是没有 ksan 功能的,我们的 mtk mtk6757-n-v1.0 这条线有, (因为 kernel 版本为 4.4)于是在此版本上可以开启 编译方式,添加 kconfig CONFIG_KASAN CONFIG_KASAN_INLINE CONFIG_TEST_KASAN CONFIG_KCOV CONFIG_SLUB CONFIG_SLUB_DEBUG CONFIG_CC_OPTIMIZE_FOR_SIZE 移除一些 CONFIG_SLUB_DEBUG_ON CONFIG_SLUB_DEBUG_PANIC_ON CONFIG_KASAN_OUTLINE CONFIG_KERNEL_LZ4 然后编译系统 启动时候,出现 log [[0.000000] c0 0 Virtual kernel memory layout:0.000000] c0 0 kasan : 0xffffff8000000000 - 技术说明 0xffffff9000000000 (64 GB) 说明 kasan 加入成功 然后,如果 kernel 里面有错误出现,则会有如下信息: [18.539668] c3 1 ================================================================== [ 18.547662] c3 1 BUG: KASAN: null-ptr-deref on address 0000000000000008 [ 18.554689] c3 1 Read of size 8 by task swapper/0/1 [ 18.559988] c3 1 CPU: 3 PID: 1 Comm: swapper/0 Tainted: GW #1 [ 18.569275] c3 1 Hardware name: Android Device [ 18.577433] c3 1 Call trace: [ 18.580739] c3 1 [<ffffffc00008b32c>] dump_backtrace+0x0/0x2c4 指示错误类型,以及栈信息 3.18.24-xxx

编译整个系统

使用 make USE_CLANG_PLATFORM_BUILD:=true SANITIZE_TARGET=address -j42 来编译系统,调整下 userdata 数据区域大小,然后刷机,此 时整个系统是处在可以检测的状态,所有应用的内存问题, 都会在运行时报出来.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 代码GG之家 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 AddressSanitizer
  • sanitizer 例子
  • 添加c代码
  • 检测效果
  • 介绍
  • UndefinedBehaviorSanitizer
  • Kernel Address Sanitizer
  • 编译整个系统
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档