前言
想必大家曾经被各种Native Crash折磨过,本地测试没啥问题,一到线上或者自动化测试就出现各种SIGSEGV、SIGABRT、SIGILL、SIGBUS、SIGFPE异常,而且堆栈还是崩溃到libc.so这种,看起来跟我们的代码没啥关系,关键还不好复现,简直毫无办法,做Android开发真的是太难了。
看看这个日志,是不是似曾相识?
--------- beginning of crash
06-07 01:53:32.465 12027 12027 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-07 01:53:32.465 12027 12027 F DEBUG : Revision: '0'
06-07 01:53:32.466 12027 12027 F DEBUG : ABI: 'arm64'
06-07 01:53:32.466 12027 12027 F DEBUG : Timestamp: 2022-06-07 01:53:32.033409857+0800
06-07 01:53:32.466 12027 12027 F DEBUG : Process uptime: 0s
06-07 01:53:32.466 12027 12027 F DEBUG : Cmdline: mediaserver64
06-07 01:53:32.466 12027 12027 F DEBUG : pid: 1139, tid: 11981, name: NPDecoder >>> mediaserver64 <<<
06-07 01:53:32.466 12027 12027 F DEBUG : uid: 1013
06-07 01:53:32.466 12027 12027 F DEBUG : tagged_addr_ctrl: 0000000000000001
06-07 01:53:32.466 12027 12027 F DEBUG : signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7c02d886f0
06-07 01:53:32.466 12027 12027 F DEBUG : x0 79748c5e568e2ddc x1 0000007ca13c3618 x2 0000000000000000 x3 0000007ca1291000
06-07 01:53:32.466 12027 12027 F DEBUG : x4 0000000001909705 x5 0000000000000000 x6 0000007c02d88808 x7 b60625655bf0252f
06-07 01:53:32.467 12027 12027 F DEBUG : x8 0000000000000080 x9 0000007ca126fed7 x10 0000000000000006 x11 0000007bfd0a81fc
06-07 01:53:32.467 12027 12027 F DEBUG : x12 9ef8a95ca9649dbe x13 e44782d5ac38720e x14 0000007bfd0a8030 x15 0000001e56307b5c
06-07 01:53:32.467 12027 12027 F DEBUG : x16 0000007c95dfdb70 x17 0000007c9844f118 x18 0000007bfaa28000 x19 b400007c13c246d0
06-07 01:53:32.467 12027 12027 F DEBUG : x20 0000007c02d88730 x21 b400007c13c67c00 x22 0000000000000415 x23 0000007c02d89000
06-07 01:53:32.467 12027 12027 F DEBUG : x24 0000000000000002 x25 b400007c13c246d0 x26 b400007c13c67c00 x27 0000007c02d89000
06-07 01:53:32.467 12027 12027 F DEBUG : x28 0000007ca13c2c28 x29 0000007c02d886f0
06-07 01:53:32.467 12027 12027 F DEBUG : lr 0000007c02d886f0 sp 0000007c02d886d0 pc 0000007c02d886f0 pst 0000000080001000
06-07 01:53:32.467 12027 12027 F DEBUG : backtrace:
06-07 01:53:32.467 12027 12027 F DEBUG : #00 pc 00000000000f86f0 [anon:stack_and_tls:11981]
再看看这个表格,有没有你的老朋友?
SIGSEGV | SEGV_MAPERR | 地址不在 /proc/self/maps 映射中 |
SEGV_ACCERR | 没有访问权限 | |
SEGV_MTESERR | MTE特有类型 | |
SIGABRT | 程序主动退出,常见调用函数abort(),raise()等 | |
SIGILL | ILL_ILLOPC | 非法操作码(opcode) |
ILL_ILLOPN | 非法操作数(operand) | |
ILL_ILLADR | 非法寻址 | |
ILL_ILLTRP | 非法trap,如_builtintrap()主动崩溃 | |
ILL_PRVOPC | 非法特权操作码(privileged opcode) | |
ILL_PRVREG | 非法特权寄存器(privileged register) | |
ILL_COPROC | 协处理器错误 | |
ILL_BADSTK | 内部堆栈错误 | |
SIGBUS | BUS_ADRALN | 访问地址未对齐 |
BUS_ADRERR | 访问不存在的物理地址 | |
BUS_OBJERR | 特定对象的硬件错误 | |
SIGFPE | FPE_INTDIV | 整数除以0 |
FPE_INTOVF | 整数溢出 | |
FPE_FLTDIV | 浮点数除以0 | |
FPE_FLTOVF | 浮点数上溢(overflow) | |
FPE_FLTUND | 浮点数下溢(underflow) | |
FPE_FLTRES | 浮点数结果不精确 | |
FPE_FLTINV | 无效的浮点运算 | |
FPE_FLTSUB | 越界 |
上日志和表格来自陈冠有(小米)大佬的Android开发太难了,Native Crash的一切!
感兴趣也可以看下英文文档:Signal Codes
所以,这些崩溃到底能不能解决?95% 以上的崩溃都能解决或者规避,大部分的系统崩溃也是如此(来自张绍文的Android开发高手课:02 | 崩溃优化(下):应用崩溃了,你应该如何去分析?)。当然这话不能随便说,主要看个人能力和团队技术积累。笔者作为一个Android Boy,更多的时候面对这些疑难杂症的崩溃问题会感觉非常的无力,毕竟Native涉及到C、C++、Linux操作系统了,已经不是同一个领域的问题。但笔者仍然期望能在瓶颈中寻找突破,我们可以被打败但不可以被打倒,对吧。卷起来,生死看淡,不服就干。
尝试复现内存错误
遇到找不到规律的问题或者无法复现的问题,有时候我们会想,要是能复现就好了。所以,如果我们知道什么样的代码会有什么样的问题,那对于排查问题的思路会起到一定的帮助。
#include <jni.h>
#include <string>
#include <android/log.h>
extern "C" JNIEXPORT jstring JNICALL
Java_com_nxg_asantest_ASanTestUtil_stringFromJNI(
JNIEnv* env,
jclass clazz) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
/**
* 测试释放后使用
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testUseAfterFree(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int *array = new int[100];
delete [] array;
int i = array[0]; // BOOM
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
/**
* 测试数组越界
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testHeapBufferOverflow(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int *array = new int[100];
array[101] = 0; // BOOM
delete [] array;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
/**
* 测试栈溢出
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testStackBufferOverflow(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int stack_array[100];
stack_array[100] = 0;
// return stack_array[argc + 100]; // BOOM
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
/**
* 测试全局栈溢出
*/
int global_array[100] = {-1};
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testGlobalBufferOverflow(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
global_array[101] = 0;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
int *ptr;
__attribute__((noinline))
void FunctionThatEscapesLocalObject() {
int local[100];
ptr = &local[0];
}
/**
* 测试返回后使用
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testUseAfterReturn(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
FunctionThatEscapesLocalObject();
ptr[0] = 1;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
/**
* 测试超出作用域使用
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testUseAfterScope(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int *p;
{
int x = 0;
p = &x;
}
*p = 5;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
/**
* 测试重复释放
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testRepeatFree(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int *p = new int[3];
delete []p;
delete []p;
delete []p;
delete []p;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
/**
* 测试内存泄露
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testMemoryLeak(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
void *p;
p = new int[7];
p = 0; // The memory is leaked here
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
以上代码来自sztaohongtao的深入浅出Android NDK之ASan检测内存越界
经过测试发现
Java_com_nxg_asantest_ASanTestUtil_testStackBufferOverflow崩溃报错:
Java_com_nxg_asantest_ASanTestUtil_testRepeatFree崩溃报错:
其它方法均未报错。
什么是Address Sanitizer
从 API 级别 27 (Android O MR 1) 开始,Android NDK 可支持 Address Sanitizer(也称为 ASan)。
ASan 是一种基于编译器的快速检测工具,用于检测原生代码中的内存错误。ASan 可以检测以下问题:
堆栈和堆缓冲区上溢/下溢
释放之后的堆使用情况
超出范围的堆栈使用情况
重复释放/错误释放
ASan 可在 32 位和 64 位 ARM 以及 x86 和 x86-64 上运行。ASan 的 CPU 开销约为 2 倍,代码大小开销在 50% 到 2 倍之间,并且内存开销很大(具体取决于您的分配模式,但约为 2 倍)。
对于 64 位 ARM,强烈建议使用 HWAddress Sanitizer。
更多介绍和集成步骤见官方文档:Address Sanitizer,笔者就不啰嗦了。
Address Sanitizer检测代码错误
按照官方文档集成Address Sanitizer后我们看看这些有问题的代码是否能被检测到。
heap-use-after-free
/**
* 测试释放后使用
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testUseAfterFree(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int *array = new int[100];
delete [] array;
int i = array[0]; // BOOM
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
日志:
--------- beginning of main
02-19 17:54:11.970 2027 2027 D ASanCrash: enter fun Java_com_nxg_asantest_ASanTestUtil_testUseAfterFree ...
02-19 17:54:11.970 2007 2007 I wrap.sh : =================================================================
02-19 17:54:11.970 2007 2007 I wrap.sh : [1m[31m==2027==ERROR: AddressSanitizer: heap-use-after-free on address 0x004e793c08e0 at pc 0x00720d020018 bp 0x007feeeb7f10 sp 0x007feeeb7f08
02-19 17:54:11.970 2007 2007 I wrap.sh : [1m[0m[1m[34mREAD of size 4 at 0x004e793c08e0 thread T0 (om.nxg.asantest)[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : #0 0x720d020014 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x3014)
02-19 17:54:11.986 2007 2007 I wrap.sh : #1 0x7225622244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:54:11.986 2007 2007 I wrap.sh : #2 0x7225611608 (/apex/com.android.art/lib64/libart.so+0x211608)
02-19 17:54:11.986 2007 2007 I wrap.sh : #3 0x7225618964 (/apex/com.android.art/lib64/libart.so+0x218964)
02-19 17:54:11.986 2007 2007 I wrap.sh : #4 0x7225684208 (/apex/com.android.art/lib64/libart.so+0x284208)
02-19 17:54:11.986 2007 2007 I wrap.sh : #5 0x7225a1e8f8 (/apex/com.android.art/lib64/libart.so+0x61e8f8)
02-19 17:54:11.986 2007 2007 I wrap.sh : #6 0x722598fa68 (/apex/com.android.art/lib64/libart.so+0x58fa68)
02-19 17:54:11.986 2007 2007 I wrap.sh : #7 0x6fe01f74 (/apex/com.android.art/javalib/arm64/boot.oat+0xb2f74)
02-19 17:54:11.986 2007 2007 I wrap.sh :
02-19 17:54:11.986 2007 2007 I wrap.sh : [1m[32m0x004e793c08e0 is located 0 bytes inside of 400-byte region [0x004e793c08e0,0x004e793c0a70)
02-19 17:54:11.986 2007 2007 I wrap.sh : [1m[0m[1m[35mfreed by thread T0 (om.nxg.asantest) here:[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : #0 0x74c9999c64 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so+0xaac64)
02-19 17:54:11.986 2007 2007 I wrap.sh : #1 0x720d01ffb4 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x2fb4)
02-19 17:54:11.986 2007 2007 I wrap.sh : #2 0x7225622244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:54:11.986 2007 2007 I wrap.sh : #3 0x722594a874 (/apex/com.android.art/lib64/libart.so+0x54a874)
02-19 17:54:11.986 2007 2007 I wrap.sh :
02-19 17:54:11.986 2007 2007 I wrap.sh : [1m[35mpreviously allocated by thread T0 (om.nxg.asantest) here:[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : #0 0x74c999947c (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so+0xaa47c)
02-19 17:54:11.986 2007 2007 I wrap.sh : #1 0x720d01ff90 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x2f90)
02-19 17:54:11.986 2007 2007 I wrap.sh : #2 0x7225622244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:54:11.986 2007 2007 I wrap.sh : #3 0x722594a874 (/apex/com.android.art/lib64/libart.so+0x54a874)
02-19 17:54:11.986 2007 2007 I wrap.sh :
02-19 17:54:11.986 2007 2007 I wrap.sh : SUMMARY: AddressSanitizer: heap-use-after-free (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x3014)
02-19 17:54:11.986 2007 2007 I wrap.sh : Shadow bytes around the buggy address:
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf2780c0: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf2780d0: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf2780e0: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf2780f0: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf278100: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : =>0x0019cf278110: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m[[1m[35mfd[1m[0m][1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf278120: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf278130: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf278140: [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[35mfd[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf278150: [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : 0x0019cf278160: [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m [1m[31mfa[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Shadow byte legend (one shadow byte represents 8 application bytes):
02-19 17:54:11.986 2007 2007 I wrap.sh : Addressable: [1m[0m00[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Partially addressable: [1m[0m01[1m[0m [1m[0m02[1m[0m [1m[0m03[1m[0m [1m[0m04[1m[0m [1m[0m05[1m[0m [1m[0m06[1m[0m [1m[0m07[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Heap left redzone: [1m[31mfa[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Freed heap region: [1m[35mfd[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Stack left redzone: [1m[31mf1[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Stack mid redzone: [1m[31mf2[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Stack right redzone: [1m[31mf3[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Stack after return: [1m[35mf5[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Stack use after scope: [1m[35mf8[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Global redzone: [1m[31mf9[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Global init order: [1m[36mf6[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Poisoned by user: [1m[34mf7[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Container overflow: [1m[34mfc[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Array cookie: [1m[31mac[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Intra object redzone: [1m[33mbb[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : ASan internal: [1m[33mfe[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Left alloca redzone: [1m[34mca[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Right alloca redzone: [1m[34mcb[1m[0m
02-19 17:54:11.986 2007 2007 I wrap.sh : Shadow gap: [1m[0mcc[1m[0m
02-19 17:54:11.987 2007 2007 I wrap.sh : ==2027==ABORTING
--------- beginning of crash
02-19 17:54:11.987 2027 2027 F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 2027 (om.nxg.asantest), pid 2027 (om.nxg.asantest)
02-19 17:54:12.022 2137 2137 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstoneProto
02-19 17:54:12.022 762 762 I tombstoned: received crash request for pid 2027
02-19 17:54:12.023 2137 2137 I crash_dump64: performing dump of process 2027 (target tid = 2027)
02-19 17:54:12.029 2137 2137 E DEBUG : failed to read /proc/uptime: Permission denied
02-19 17:54:12.238 2137 2137 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
02-19 17:54:12.238 2137 2137 F DEBUG : Build fingerprint: 'google/flame/flame:12/SQ1A.211205.008/7888514:user/release-keys'
02-19 17:54:12.238 2137 2137 F DEBUG : Revision: 'MP1.0'
02-19 17:54:12.238 2137 2137 F DEBUG : ABI: 'arm64'
02-19 17:54:12.238 2137 2137 F DEBUG : Timestamp: 2023-02-19 17:54:12.029573192+0800
02-19 17:54:12.238 2137 2137 F DEBUG : Process uptime: 0s
02-19 17:54:12.238 2137 2137 F DEBUG : Cmdline: com.nxg.asantest
02-19 17:54:12.238 2137 2137 F DEBUG : pid: 2027, tid: 2027, name: om.nxg.asantest >>> com.nxg.asantest <<<
02-19 17:54:12.238 2137 2137 F DEBUG : uid: 10229
02-19 17:54:12.238 2137 2137 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
02-19 17:54:12.238 2137 2137 F DEBUG : Abort message: '=================================================================
02-19 17:54:12.238 2137 2137 F DEBUG : ==2027==ERROR: AddressSanitizer: heap-use-after-free on address 0x004e793c08e0 at pc 0x00720d020018 bp 0x007feeeb7f10 sp 0x007feeeb7f08
02-19 17:54:12.238 2137 2137 F DEBUG : READ of size 4 at 0x004e793c08e0 thread T0 (om.nxg.asantest)
02-19 17:54:12.238 2137 2137 F DEBUG : #0 0x720d020014 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x3014)
02-19 17:54:12.238 2137 2137 F DEBUG : #1 0x7225622244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:54:12.238 2137 2137 F DEBUG : #2 0x7225611608 (/apex/com.android.art/lib64/libart.so+0x211608)
02-19 17:54:12.238 2137 2137 F DEBUG : #3 0x7225618964 (/apex/com.android.art/lib64/libart.so+0x218964)
02-19 17:54:12.238 2137 2137 F DEBUG : #4 0x7225684208 (/apex/com.android.art/lib64/libart.so+0x284208)
02-19 17:54:12.238 2137 2137 F DEBUG : #5 0x7225a1e8f8 (/apex/com.android.art/lib64/libart.so+0x61e8f8)
02-19 17:54:12.238 2137 2137 F DEBUG : #6 0x722598fa68 (/apex/com.android.art/lib64/libart.so+0x58fa68)
02-19 17:54:12.238 2137 2137 F DEBUG : #7 0x6fe01f74 (/apex/com.android.art/javalib/arm64/boot.oat+0xb2f74)
02-19 17:54:12.238 2137 2137 F DEBUG :
02-19 17:54:12.238 2137 2137 F DEBUG : 0x004e793c08e0 is located 0 bytes inside of 400-byte region [0x004e793c08e0,0x004e793c0a70)
02-19 17:54:12.238 2137 2137 F DEBUG : freed by thread T0 (om.nxg.asantest) here:
02-19 17:54:12.238 2137 2137 F DEBUG : #0 0x74c9999c64 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so+0xaac64)
02-19 17:54:12.238 2137 2137 F DEBUG : #1 0x720d01ffb4 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x2fb4)
02-19 17:54:12.238 2137 2137 F DEBUG : #2 0x7225622244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:54:12.238 2137 2137 F DEBUG : #3 0x722594a874 (/apex/com.android.art/lib64/libart.so+0x54a874)
02-19 17:54:12.238 2137 2137 F DEBUG :
02-19 17:54:12.238 2137 2137 F DEBUG : previously allocated by thread T0 (om.nxg.asantest) here:
02-19 17:54:12.238 2137 2137 F DEBUG : #0 0x74c999947c (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so+0xaa47c)
02-19 17:54:12.238 2137 2137 F DEBUG : #1 0x720d01ff90 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x2f90)
02-19 17:54:12.238 2137 2137 F DEBUG : #2 0x7225622244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:54:12.238 2137 2137 F DEBUG : #3 0x722594a874 (/apex/com.android.art/lib64/libart.so+0x54a874)
02-19 17:54:12.238 2137 2137 F DEBUG :
02-19 17:54:12.238 2137 2137 F DEBUG : SUMMARY: AddressSanitizer: heap-use-after-free (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x3014)
02-19 17:54:12.238 2137 2137 F DEBUG : Shadow bytes around the buggy address:
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf2780c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf2780d0: fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa fa
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf2780e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf2780f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf278100: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
02-19 17:54:12.238 2137 2137 F DEBUG : =>0x0019cf278110: fd fd fa fa fa fa fa fa fa fa fa fa[fd]fd fd fd
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf278120: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf278130: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf278140: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf278150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
02-19 17:54:12.238 2137 2137 F DEBUG : 0x0019cf278160: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
02-19 17:54:12.238 2137 2137 F DEBUG : Shadow byte legend (one shadow byte represents 8 application bytes):
02-19 17:54:12.238 2137 2137 F DEBUG : Addressable: 00
02-19 17:54:12.238 2137 2137 F DEBUG : Partially addressable: 01 02 03 04 05 06 07
02-19 17:54:12.238 2137 2137 F DEBUG : Heap left redzone: fa
02-19 17:54:12.238 2137 2137 F DEBUG : Freed heap region: fd
02-19 17:54:12.238 2137 2137 F DEBUG : Stack left redzone: f1
02-19 17:54:12.238 2137 2137 F DEBUG : Stack mid redzone: f2
02-19 17:54:12.238 2137 2137 F DEBUG : Stack right redzone: f3
02-19 17:54:12.238 2137 2137 F DEBUG : Stack after return: f5
02-19 17:54:12.238 2137 2137 F DEBUG : Stack use after scope: f8
02-19 17:54:12.238 2137 2137 F DEBUG : Global redzone: f9
02-19 17:54:12.238 2137 2137 F DEBUG : Global init order: f6
02-19 17:54:12.238 2137 2137 F DEBUG : Poisoned by user: f7
02-19 17:54:12.238 2137 2137 F DEBUG : Container overflow: fc
02-19 17:54:12.238 2137 2137 F DEBUG : Array cookie: ac
02-19 17:54:12.238 2137 2137 F DEBUG : Intra object redzone: bb
02-19 17:54:12.238 2137 2137 F DEBUG : ASan internal: fe
02-19 17:54:12.238 2137 2137 F DEBUG : Left alloca redzone: ca
02-19 17:54:12.238 2137 2137 F DEBUG : Right alloca redzone: cb
02-19 17:54:12.238 2137 2137 F DEBUG : Shadow gap: cc
02-19 17:54:12.238 2137 2137 F DEBUG : '
02-19 17:54:12.238 2137 2137 F DEBUG : x0 0000000000000000 x1 00000000000007eb x2 0000000000000006 x3 0000007feeeb7190
02-19 17:54:12.238 2137 2137 F DEBUG : x4 0000000000000000 x5 0000000000000000 x6 0000000000000000 x7 0000000000000000
02-19 17:54:12.238 2137 2137 F DEBUG : x8 00000000000000f0 x9 ea2bc60daeb39863 x10 0000000000000000 x11 ffffff80fffffbdf
02-19 17:54:12.238 2137 2137 F DEBUG : x12 0000000000000001 x13 0000000000000037 x14 0000000000000030 x15 00000074c9938d54
02-19 17:54:12.238 2137 2137 F DEBUG : x16 00000074df784050 x17 00000074df760eb0 x18 00000074e69d2000 x19 00000000000007eb
02-19 17:54:12.238 2137 2137 F DEBUG : x20 00000000000007eb x21 00000000ffffffff x22 00000074c9a77040 x23 00000074c9b00e00
02-19 17:54:12.238 2137 2137 F DEBUG : x24 000000720d020018 x25 0000000000000001 x26 0000000018380001 x27 00000057793e8100
02-19 17:54:12.238 2137 2137 F DEBUG : x28 0000007feeeb7f90 x29 0000007feeeb7210
02-19 17:54:12.238 2137 2137 F DEBUG : lr 00000074df713ba0 sp 0000007feeeb7170 pc 00000074df713bcc pst 0000000000000000
02-19 17:54:12.238 2137 2137 F DEBUG : backtrace:
02-19 17:54:12.238 2137 2137 F DEBUG : #00 pc 000000000004fbcc /apex/com.android.runtime/lib64/bionic/libc.so (abort+164) (BuildId: ba489d4985c0cf173209da67405662f9)
02-19 17:54:12.238 2137 2137 F DEBUG : #01 pc 000000000004d60c /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
02-19 17:54:12.238 2137 2137 F DEBUG : #02 pc 000000000004c5d8 /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
02-19 17:54:12.238 2137 2137 F DEBUG : #03 pc 00000000000a3300 /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
02-19 17:54:12.238 2137 2137 F DEBUG : #04 pc 00000000000a47dc /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
02-19 17:54:12.238 2137 2137 F DEBUG : #05 pc 00000000000a5084 /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so (__asan_report_load4+44) (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
02-19 17:54:12.238 2137 2137 F DEBUG : #06 pc 0000000000003014 /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so (Java_com_nxg_asantest_ASanTestUtil_testUseAfterFree+216) (BuildId: b3fbe503c7eb01bc04ef889c04f547510728d2a0)
02-19 17:54:12.238 2137 2137 F DEBUG : #07 pc 0000000000222244 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #08 pc 0000000000211608 /apex/com.android.art/lib64/libart.so (nterp_helper+152) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #09 pc 00000000000004cc [anon:dalvik-classes3.dex extracted in memory from /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/base.apk!classes3.dex] (com.nxg.asantest.MainActivity.onBtnUseAfterFreeClick+0)
02-19 17:54:12.238 2137 2137 F DEBUG : #10 pc 0000000000218964 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #11 pc 0000000000284208 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+188) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #12 pc 000000000061e8f8 /apex/com.android.art/lib64/libart.so (_jobject* art::InvokeMethod<(art::PointerSize)8>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long)+1384) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #13 pc 000000000058fa68 /apex/com.android.art/lib64/libart.so (art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*)+52) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #14 pc 00000000000b2f74 /apex/com.android.art/javalib/arm64/boot.oat (art_jni_trampoline+132) (BuildId: 715d0a044ea13bcf499cd6094001f85c3246944e)
02-19 17:54:12.238 2137 2137 F DEBUG : #15 pc 0000000000212520 /apex/com.android.art/lib64/libart.so (nterp_helper+4016) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #16 pc 00000000000bad4a [anon:dalvik-classes.dex extracted in memory from /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/base.apk] (androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick+46)
02-19 17:54:12.238 2137 2137 F DEBUG : #17 pc 0000000000706184 /system/framework/arm64/boot-framework.oat (android.view.View.performClick+148) (BuildId: 129a000a0763e5ab511b5552db418f26d6b2c92f)
02-19 17:54:12.238 2137 2137 F DEBUG : #18 pc 0000000000212520 /apex/com.android.art/lib64/libart.so (nterp_helper+4016) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #19 pc 000000000020c8ee [anon:dalvik-classes.dex extracted in memory from /data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/base.apk] (com.google.android.material.button.MaterialButton.performClick+6)
02-19 17:54:12.238 2137 2137 F DEBUG : #20 pc 0000000000640174 /system/framework/arm64/boot-framework.oat (android.view.View$PerformClick.run+164) (BuildId: 129a000a0763e5ab511b5552db418f26d6b2c92f)
02-19 17:54:12.238 2137 2137 F DEBUG : #21 pc 00000000004efe30 /system/framework/arm64/boot-framework.oat (android.os.Handler.dispatchMessage+80) (BuildId: 129a000a0763e5ab511b5552db418f26d6b2c92f)
02-19 17:54:12.238 2137 2137 F DEBUG : #22 pc 00000000004f2ccc /system/framework/arm64/boot-framework.oat (android.os.Looper.loopOnce+1036) (BuildId: 129a000a0763e5ab511b5552db418f26d6b2c92f)
02-19 17:54:12.238 2137 2137 F DEBUG : #23 pc 00000000004f2824 /system/framework/arm64/boot-framework.oat (android.os.Looper.loop+516) (BuildId: 129a000a0763e5ab511b5552db418f26d6b2c92f)
02-19 17:54:12.238 2137 2137 F DEBUG : #24 pc 00000000002cefdc /system/framework/arm64/boot-framework.oat (android.app.ActivityThread.main+732) (BuildId: 129a000a0763e5ab511b5552db418f26d6b2c92f)
02-19 17:54:12.238 2137 2137 F DEBUG : #25 pc 0000000000218be8 /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #26 pc 0000000000284224 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+216) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #27 pc 000000000061e8f8 /apex/com.android.art/lib64/libart.so (_jobject* art::InvokeMethod<(art::PointerSize)8>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long)+1384) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #28 pc 000000000058fa68 /apex/com.android.art/lib64/libart.so (art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*)+52) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #29 pc 00000000000b2f74 /apex/com.android.art/javalib/arm64/boot.oat (art_jni_trampoline+132) (BuildId: 715d0a044ea13bcf499cd6094001f85c3246944e)
02-19 17:54:12.238 2137 2137 F DEBUG : #30 pc 000000000081a48c /system/framework/arm64/boot-framework.oat (com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run+140) (BuildId: 129a000a0763e5ab511b5552db418f26d6b2c92f)
02-19 17:54:12.238 2137 2137 F DEBUG : #31 pc 0000000000213344 /apex/com.android.art/lib64/libart.so (nterp_helper+7636) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #32 pc 000000000024b69e /system/framework/framework.jar (com.android.internal.os.WrapperInit.main+182)
02-19 17:54:12.238 2137 2137 F DEBUG : #33 pc 0000000000218be8 /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #34 pc 0000000000284224 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+216) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #35 pc 000000000061f050 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+448) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #36 pc 000000000061f514 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #37 pc 0000000000497b24 /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+616) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #38 pc 00000000000aeac4 /system/lib64/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+120) (BuildId: e6f683896552e00197598ae4519fb02d)
02-19 17:54:12.238 2137 2137 F DEBUG : #39 pc 00000000000b65d0 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::callMain(android::String8 const&, _jclass*, android::Vector<android::String8> const&)+336) (BuildId: e6f683896552e00197598ae4519fb02d)
02-19 17:54:12.238 2137 2137 F DEBUG : #40 pc 0000000000002980 /system/bin/app_process64 (android::AppRuntime::onStarted()+68) (BuildId: 4ecb2c57d6667e4a94a73568ce392d22)
02-19 17:54:12.238 2137 2137 F DEBUG : #41 pc 000000000018cba8 /system/framework/arm64/boot-framework.oat (art_jni_trampoline+88) (BuildId: 129a000a0763e5ab511b5552db418f26d6b2c92f)
02-19 17:54:12.238 2137 2137 F DEBUG : #42 pc 0000000000211608 /apex/com.android.art/lib64/libart.so (nterp_helper+152) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #43 pc 00000000002484e0 /system/framework/framework.jar (com.android.internal.os.RuntimeInit.main+48)
02-19 17:54:12.238 2137 2137 F DEBUG : #44 pc 0000000000218be8 /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #45 pc 0000000000284224 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+216) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #46 pc 000000000061f050 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+448) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #47 pc 000000000061f514 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #48 pc 0000000000497b24 /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+616) (BuildId: e6c658201ef1ec3760112fa1b838ab2c)
02-19 17:54:12.238 2137 2137 F DEBUG : #49 pc 00000000000aeac4 /system/lib64/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+120) (BuildId: e6f683896552e00197598ae4519fb02d)
02-19 17:54:12.238 2137 2137 F DEBUG : #50 pc 00000000000ba05c /system/lib64/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)+836) (BuildId: e6f683896552e00197598ae4519fb02d)
02-19 17:54:12.238 2137 2137 F DEBUG : #51 pc 000000000000258c /system/bin/app_process64 (main+1336) (BuildId: 4ecb2c57d6667e4a94a73568ce392d22)
02-19 17:54:12.238 2137 2137 F DEBUG : #52 pc 00000000000488c8 /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+96) (BuildId: ba489d4985c0cf173209da67405662f9)
02-19 17:54:12.249 762 762 E tombstoned: Tombstone written to: tombstone_23
ASan检测到了heap-use-after-free并主动的抛出了异常。
[1m[31m==2027==ERROR: AddressSanitizer: heap-use-after-free on address 0x004e793c08e0 at pc 0x00720d020018 bp 0x007feeeb7f10 sp 0x007feeeb7f08
[1m[0m[1m[34mREAD of size 4 at 0x004e793c08e0 thread T0 (om.nxg.asantest)[1m[0m
#0 0x720d020014 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x3014)
但是我们并不知道具体报错是哪行代码,日志只告诉了我们报错在libasantest.so的内存地址0x3014,这时候addr2line就派上用场了。
addr2line全写是address to line,ta是将函数地址解析成文件名或行号的工具。给出一个可执行文件中的地址或一个可重定位对象中的偏移部分的地址,使用调试信息来找出与之相关的文件名和行号。
addr2line在NDK的这个路径:
#注意NDK 23貌似已经移除了arm-linux-androideabi-addr2line
~/Android/Sdk/ndk/21.4.7075529/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin$
打开命令行终端,执行:./arm-linux-androideabi-addr2line -h查看使用帮助
Usage: ./aarch64-linux-android-addr2line [option(s)] [addr(s)]
Convert addresses into line number/file name pairs.
If no addresses are specified on the command line, they will be read from stdin
The options are:
@<file> Read options from <file>
-a --addresses Show addresses
-b --target=<bfdname> Set the binary file format
-e --exe=<executable> Set the input file name (default is a.out)
-i --inlines Unwind inlined functions
-j --section=<name> Read section-relative offsets instead of addresses
-p --pretty-print Make the output easier to read for humans
-s --basenames Strip directory names
-f --functions Show function names
-C --demangle[=style] Demangle function names
-h --help Display this information
-v --version Display the program's version
使用-e指定so文件,使用-a查询内存地址对应的代码行,执行:
./aarch64-linux-android-addr2line -e /work/AndroidStudioProjects/AndroidDevelopmentPractices/ASanTest/app/src/main/cpp/obj/arm64-v8a/libasantest.so -a 0x3014
可以看到,打印了指定文件的代码行数:
/work/AndroidStudioProjects/AndroidDevelopmentPractices/ASanTest/app/src/main/cpp/native-lib.cpp:21
精准的定位到了我们的代码,确实很强大。
如果发现addr2line定位不到代码行,比如返回?啥的,原因可能是so是release版本,建议使用debug版本测试,或者保留符号表。CMAKE开启debug模式:
set(CMAKE_BUILD_TYPE DEBUG) # 调试模式,方便addr2line定位代码
heap-buffer-overflow
/**
* 测试数组越界
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testHeapBufferOverflow(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int *array = new int[100];
array[101] = 0; // BOOM
delete [] array;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
ASan检测到了heap-buffer-overflow并主动的抛出了异常。
02-19 17:57:24.109 3088 3088 I wrap.sh : [1m[31m==3095==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x004e0ef77d14 at pc 0x0078b1f95118 bp 0x007fe23b0850 sp 0x007fe23b0848
02-19 17:57:24.109 3088 3088 I wrap.sh : [1m[0m[1m[34mWRITE of size 4 at 0x004e0ef77d14 thread T0 (om.nxg.asantest)[1m[0m
02-19 17:57:24.126 3088 3088 I wrap.sh : #0 0x78b1f95114 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x3114)
02-19 17:57:24.126 3088 3088 I wrap.sh : #1 0x792e222244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:57:24.126 3088 3088 I wrap.sh : #2 0x792e211608 (/apex/com.android.art/lib64/libart.so+0x211608)
02-19 17:57:24.126 3088 3088 I wrap.sh : #3 0x792e218964 (/apex/com.android.art/lib64/libart.so+0x218964)
02-19 17:57:24.127 3088 3088 I wrap.sh : #4 0x792e284208 (/apex/com.android.art/lib64/libart.so+0x284208)
02-19 17:57:24.127 3088 3088 I wrap.sh : #5 0x792e61e8f8 (/apex/com.android.art/lib64/libart.so+0x61e8f8)
02-19 17:57:24.127 3088 3088 I wrap.sh : #6 0x792e58fa68 (/apex/com.android.art/lib64/libart.so+0x58fa68)
02-19 17:57:24.127 3088 3088 I wrap.sh : #7 0x706d6f74 (/apex/com.android.art/javalib/arm64/boot.oat+0xb2f74)
addr2line定位到native-lib.cpp:31
对应代码如下:
stack-buffer-overflow
/**
* 测试栈溢出
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testStackBufferOverflow(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int stack_array[100];
stack_array[100] = 0;
// return stack_array[argc + 100]; // BOOM
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
ASan检测到了stack-buffer-overflow并主动的抛出了异常。
02-19 17:57:27.190 3174 3174 I wrap.sh : =================================================================
02-19 17:57:27.191 3174 3174 I wrap.sh : [1m[31m==3185==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x007fc42f3650 at pc 0x0079cf3ed340 bp 0x007fc42f3490 sp 0x007fc42f3488
02-19 17:57:27.191 3174 3174 I wrap.sh : [1m[0m[1m[34mWRITE of size 4 at 0x007fc42f3650 thread T0 (om.nxg.asantest)[1m[0m
02-19 17:57:27.206 3174 3174 I wrap.sh : #0 0x79cf3ed33c (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x333c)
02-19 17:57:27.207 3174 3174 I wrap.sh : #1 0x7a4ce22244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:57:27.207 3174 3174 I wrap.sh : #2 0x7a4ce11608 (/apex/com.android.art/lib64/libart.so+0x211608)
02-19 17:57:27.207 3174 3174 I wrap.sh : #3 0x7a4ce18964 (/apex/com.android.art/lib64/libart.so+0x218964)
02-19 17:57:27.207 3174 3174 I wrap.sh : #4 0x7a4ce84208 (/apex/com.android.art/lib64/libart.so+0x284208)
02-19 17:57:27.207 3174 3174 I wrap.sh : #5 0x7a4d21e8f8 (/apex/com.android.art/lib64/libart.so+0x61e8f8)
02-19 17:57:27.207 3174 3174 I wrap.sh : #6 0x7a4d18fa68 (/apex/com.android.art/lib64/libart.so+0x58fa68)
02-19 17:57:27.207 3174 3174 I wrap.sh : #7 0x6f547f74 (/apex/com.android.art/javalib/arm64/boot.oat+0xb2f74)
addr2line定位到native-lib.cpp:42
对应代码如下:
global-buffer-overflow
/**
* 测试全局栈溢出
*/
int global_array[100] = {-1};
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testGlobalBufferOverflow(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
global_array[101] = 0;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
ASan检测到了global-buffer-overflow并主动的抛出了异常。
02-19 17:57:30.360 3282 3282 I wrap.sh : [1m[31m==3300==ERROR: AddressSanitizer: global-buffer-overflow on address 0x006d4bc22194 at pc 0x006d4bc184d0 bp 0x007ff88fe320 sp 0x007ff88fe318
02-19 17:57:30.360 3282 3282 I wrap.sh : [1m[0m[1m[34mWRITE of size 4 at 0x006d4bc22194 thread T0 (om.nxg.asantest)[1m[0m
02-19 17:57:30.378 3282 3282 I wrap.sh : #0 0x6d4bc184cc (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x34cc)
02-19 17:57:30.378 3282 3282 I wrap.sh : #1 0x6dcbc22244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:57:30.378 3282 3282 I wrap.sh : #2 0x6dcbc11608 (/apex/com.android.art/lib64/libart.so+0x211608)
02-19 17:57:30.378 3282 3282 I wrap.sh : #3 0x6dcbc18964 (/apex/com.android.art/lib64/libart.so+0x218964)
02-19 17:57:30.378 3282 3282 I wrap.sh : #4 0x6dcbc84208 (/apex/com.android.art/lib64/libart.so+0x284208)
02-19 17:57:30.378 3282 3282 I wrap.sh : #5 0x6dcc01e8f8 (/apex/com.android.art/lib64/libart.so+0x61e8f8)
02-19 17:57:30.378 3282 3282 I wrap.sh : #6 0x6dcbf8fa68 (/apex/com.android.art/lib64/libart.so+0x58fa68)
02-19 17:57:30.378 3282 3282 I wrap.sh : #7 0x6f9e0f74 (/apex/com.android.art/javalib/arm64/boot.oat+0xb2f74)
addr2line定位到native-lib.cpp:53
对应代码如下:
stack-use-after-scope
/**
* 测试超出作用域使用
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testUseAfterScope(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int *p;
{
int x = 0;
p = &x;
}
*p = 5;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
ASan检测到了stack-use-after-scope并主动的抛出了异常。
02-19 17:57:44.159 3512 3512 I wrap.sh : [1m[31m==3521==ERROR: AddressSanitizer: stack-use-after-scope on address 0x007feb36d4e0 at pc 0x00789a18d9bc bp 0x007feb36d4b0 sp 0x007feb36d4a8
02-19 17:57:44.159 3512 3512 I wrap.sh : [1m[0m[1m[34mWRITE of size 4 at 0x007feb36d4e0 thread T0 (om.nxg.asantest)[1m[0m
02-19 17:57:44.184 3512 3512 I wrap.sh : #0 0x789a18d9b8 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x39b8)
02-19 17:57:44.184 3512 3512 I wrap.sh : #1 0x7921a22244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:57:44.184 3512 3512 I wrap.sh : #2 0x7921a11608 (/apex/com.android.art/lib64/libart.so+0x211608)
02-19 17:57:44.184 3512 3512 I wrap.sh : #3 0x7921a18964 (/apex/com.android.art/lib64/libart.so+0x218964)
02-19 17:57:44.184 3512 3512 I wrap.sh : #4 0x7921a84208 (/apex/com.android.art/lib64/libart.so+0x284208)
02-19 17:57:44.184 3512 3512 I wrap.sh : #5 0x7921e1e8f8 (/apex/com.android.art/lib64/libart.so+0x61e8f8)
02-19 17:57:44.184 3512 3512 I wrap.sh : #6 0x7921d8fa68 (/apex/com.android.art/lib64/libart.so+0x58fa68)
02-19 17:57:44.184 3512 3512 I wrap.sh : #7 0x6fceef74 (/apex/com.android.art/javalib/arm64/boot.oat+0xb2f74)
addr2line定位到native-lib.cpp:83
对应代码如下:
attempting double-free
/**
* 测试重复释放
*/
extern "C" JNIEXPORT void Java_com_nxg_asantest_ASanTestUtil_testRepeatFree(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "enter fun %s ...", __FUNCTION__ );
int *p = new int[3];
delete []p;
delete []p;
delete []p;
delete []p;
__android_log_print(ANDROID_LOG_DEBUG, "ASanCrash", "leave fun %s ...", __FUNCTION__ );
}
ASan检测到了attempting double-free并主动的抛出了异常。
02-19 17:57:47.308 3665 3665 I wrap.sh : =================================================================
02-19 17:57:47.309 3665 3665 I wrap.sh : [1m[31m==3685==ERROR: AddressSanitizer: attempting double-free on 0x003d32b6c010 in thread T0 (om.nxg.asantest):
02-19 17:57:47.332 3665 3665 I wrap.sh : [1m[0m #0 0x7c1233dc64 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libclang_rt.asan-aarch64-android.so+0xaac64)
02-19 17:57:47.332 3665 3665 I wrap.sh : #1 0x78e31e8b08 (/data/app/~~O3c2gJpllNHK6xBZIypJyQ==/com.nxg.asantest-iQvQxnZ3heMOyVK67qkkyw==/lib/arm64/libasantest.so+0x3b08)
02-19 17:57:47.332 3665 3665 I wrap.sh : #2 0x7964222244 (/apex/com.android.art/lib64/libart.so+0x222244)
02-19 17:57:47.332 3665 3665 I wrap.sh : #3 0x7964211608 (/apex/com.android.art/lib64/libart.so+0x211608)
02-19 17:57:47.332 3665 3665 I wrap.sh : #4 0x7964218964 (/apex/com.android.art/lib64/libart.so+0x218964)
02-19 17:57:47.332 3665 3665 I wrap.sh : #5 0x7964284208 (/apex/com.android.art/lib64/libart.so+0x284208)
02-19 17:57:47.332 3665 3665 I wrap.sh : #6 0x796461e8f8 (/apex/com.android.art/lib64/libart.so+0x61e8f8)
02-19 17:57:47.332 3665 3665 I wrap.sh : #7 0x796458fa68 (/apex/com.android.art/lib64/libart.so+0x58fa68)
02-19 17:57:47.332 3665 3665 I wrap.sh : #8 0x70f73f74 (/apex/com.android.art/javalib/arm64/boot.oat+0xb2f74)
addr2line定位到native-lib.cpp:94
对应代码如下:
进过测试,ASan 确实检测以下问题:
堆栈和堆缓冲区上溢/下溢
释放之后的堆使用情况
超出范围的堆栈使用情况
重复释放/错误释放
但stack-use-after-return没检测出来,暂时不知道咋回事,需要了解的可以看这里:AddressSanitizerExampleUseAfterReturn
关于内存泄露检测,暂时还先不管,后面另外写一篇文章来单独讲讲。
一些注意事项
无法检测代码错误?
可能是编译器做了优化。参考官方WIKI:
Q: Why didn't ASan report an obviously invalid memory access in my code?
A1: If your errors is too obvious, compiler might have already optimized it out by the time Asan runs.
A2: Another, C-only option is accesses to global common symbols which are not protected by Asan (you can use -fno-common to disable generation of common symbols and hopefully detect more bugs).
A3: If _FORTIFY_SOURCE is enabled, ASan may have false positives, see next question.
支持Android O MR1(API 级别 27)之前的版本
上面提到的wrap.sh脚本只支持Android O MR1(API 级别 27)及之后的系统版本,针对低版本如Android 5.0,我们可以使用asan_device_setup脚本手动安装ASan到设备中。
在设备中安装Address Sanitizer
准备工作
● 设备需要root
● 找到asan_device_setup脚本
关于asan_device_setup脚本,在Android SDK自带的ndk中,其脚本路径为:
/ndk/23.1.7779620/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/12.0.8/bin
注意:不同的NDK版本路径可能稍微不同
asan_device_setup 使用说明
xiangang@xiangang-ubuntu:~/Android/Sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/12.0.8/bin$ ./asan_device_setup -h
usage: ./asan_device_setup [--revert] [--device device-id] [--lib path] [--extra-options options]
--revert: Uninstall ASan from the device.
--lib: Path to ASan runtime library.
--extra-options: Extra ASAN_OPTIONS.
--device: Install to the given device. Use 'adb devices' to find
device-id.
--use-su: Use 'su -c' prefix for every adb command instead of using
'adb root' once.
安装
执行adb devices命令,查看已连接的设备,确保adb只连接一个设备的情况下,通过执行./asan_device_setup 命令进行安装。如果adb连接了多个设备,就会报错error: more than one device/emulator。
如何确保adb只连接一个设备?
首先拔掉所有通过USB连接电脑的设备,再执行adb kill-server或者adb disconnect,然后再重新执行adb connect 连接目标设备即可。当然最好再次执行adb devices检查是否只连接了一个设备,最后重新执行./asan_device_setup,第一次会先root设备,然后再重新执行一次./asan_device_setup即可。
当然也可以使用--device指定设备:
--device: Install to the given device. Use 'adb devices' to find
device-id.
如果设备无法root,可以尝试加上--use-su
--use-su: Use 'su -c' prefix for every adb command instead of using
'adb root' once.
如果脚本执行成功,那么设备就会自动重启。示例日志如下:
xiangang@xiangang-ubuntu:/work/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.7/bin$ ls -l
总用量 16
-rwxr-xr-x 1 lbrd lbrd 13721 5月 22 2019 asan_device_setup
xiangang@xiangang-ubuntu:/work/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.7/bin$ adb connect 192.168.1.128:5656
connected to 192.168.1.128:5656
xiangang@xiangang-ubuntu:/work/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.7/bin$ ls
asan_device_setup
xiangang@xiangang-ubuntu:/work/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.7/bin$ ./asan_device_setup
>> Remounting /system rw
restarting adbd as root
error: closed
xiangang@xiangang-ubuntu:/work/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.7/bin$ ./asan_device_setup
>> Remounting /system rw
adbd is already running as root
remount succeeded
Target architecture: arm
>> Copying files from the device
/system/lib/libclang_rt.asan-arm-android.so: 1 file pulled, 0 skipped. 9.6 MB/s (2112004 bytes in 0.209s)
/system/bin/app_process32: 1 file pulled, 0 skipped. 3.6 MB/s (29012 bytes in 0.008s)
adb: error: failed to stat remote object '/system/bin/app_process.wrap': No such file or directory
adb: error: failed to stat remote object '/system/bin/asanwrapper': No such file or directory
>> New installation
>> Generating wrappers
只在 new/ 存在:app_process.wrap
只在 new/ 存在:asanwrapper
文件 old/libclang_rt.asan-arm-android.so 和 new/libclang_rt.asan-arm-android.so 不同
>> Pushing files to the device
Installing /system/lib/libclang_rt.asan-arm-android.so 644
/tmp/tmp.CH44fgn4x2/new/libclang_rt.asan-arm-android.so: 1 file pushed, 0 skipped. 2517.8 MB/s (2110248 bytes in 0.001s)
Installing /system/bin/app_process32 755 u:object_r:zygote_exec:s0
/tmp/tmp.CH44fgn4x2/new/app_process32: 1 file pushed, 0 skipped. 82.7 MB/s (29012 bytes in 0.000s)
Installing /system/bin/app_process.wrap 755 u:object_r:zygote_exec:s0
/tmp/tmp.CH44fgn4x2/new/app_process.wrap: 1 file pushed, 0 skipped. 2.4 MB/s (242 bytes in 0.000s)
Installing /system/bin/asanwrapper 755 u:object_r:zygote_exec:s0
/tmp/tmp.CH44fgn4x2/new/asanwrapper: 1 file pushed, 0 skipped. 0.7 MB/s (67 bytes in 0.000s)
>> Restarting shell (asynchronous)
>> Please wait until the device restarts
xiangang@xiangang-ubuntu:/work/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.7/bin$
建议看下asan_device_setup脚本是怎么写的,可以参考自己写一些有用的测试脚本。
卸载Address Sanitizer
在实际测试中,发现安装了ASan会导致dumpsys meminfo的数据受到影响,从而导致性能监控内存失效。可能是因为ASan的关系,目前没有解决办法,只能卸载ASan了.
执行: ./asan_device_setup --revert 卸载ASan。
更多问题建议仔细阅读官方WIKI:AddressSanitizer Github WIKI或搜索issues
Address Sanitizer实战
一个实际的项目排查过程供大家参考。
SUMMARY: AddressSanitizer: double-free (/system/lib/libclang_rt.asan-arm-android.so+0xafe03)检测到是double-free,参照前面有问题的代码写法,我们很容易排查到问题。但是不会有有人这样写,所以像这种double-free通常都是多线程操作同一个static变量引起的。
截图中8314跟8026线程调用同一个方法操作static指针获取了GetByteArrayElements的返回值并且都free了,因为是同一个地址,造成double free。8314和8026(single-pool-3-t)线程是Java线程池中的线程,
写在最后,首先非常感谢您耐心阅读完整篇文章,坚持写原创且基于实战的文章不是件容易的事,如果本文刚好对您有点帮助,欢迎您给文章点赞评论,您的鼓励是笔者坚持不懈的动力。若文章有不对之处也欢迎指正,再次感谢。
参考资料
Android官方Address Sanitizer入门教程
Google官方AddressSanitizer WIKI