当前位置: 首页 > news >正文

Android稳定性系列-01-使用 Address Sanitizer检测原生代码中的内存错误

前言

想必大家曾经被各种Native Crash折磨过,本地测试没啥问题,一到线上或者自动化测试就出现各种SIGSEGV、SIGABRT、SIGILL、SIGBUS、SIGFPE异常,而且堆栈还是崩溃到libc.so这种,看起来跟我们的代码没啥关系,关键还不好复现,简直毫无办法,做Android开发真的是太难了。

看看这个日志,是不是似曾相识?

--------- beginning of crash06-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+080006-07 01:53:32.466 12027 12027 F DEBUG   : Process uptime: 0s06-07 01:53:32.466 12027 12027 F DEBUG   : Cmdline: mediaserver6406-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: 101306-07 01:53:32.466 12027 12027 F DEBUG   : tagged_addr_ctrl: 000000000000000106-07 01:53:32.466 12027 12027 F DEBUG   : signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7c02d886f006-07 01:53:32.466 12027 12027 F DEBUG   :     x0  79748c5e568e2ddc  x1  0000007ca13c3618  x2  0000000000000000  x3  0000007ca129100006-07 01:53:32.466 12027 12027 F DEBUG   :     x4  0000000001909705  x5  0000000000000000  x6  0000007c02d88808  x7  b60625655bf0252f06-07 01:53:32.467 12027 12027 F DEBUG   :     x8  0000000000000080  x9  0000007ca126fed7  x10 0000000000000006  x11 0000007bfd0a81fc06-07 01:53:32.467 12027 12027 F DEBUG   :     x12 9ef8a95ca9649dbe  x13 e44782d5ac38720e  x14 0000007bfd0a8030  x15 0000001e56307b5c06-07 01:53:32.467 12027 12027 F DEBUG   :     x16 0000007c95dfdb70  x17 0000007c9844f118  x18 0000007bfaa28000  x19 b400007c13c246d006-07 01:53:32.467 12027 12027 F DEBUG   :     x20 0000007c02d88730  x21 b400007c13c67c00  x22 0000000000000415  x23 0000007c02d8900006-07 01:53:32.467 12027 12027 F DEBUG   :     x24 0000000000000002  x25 b400007c13c246d0  x26 b400007c13c67c00  x27 0000007c02d8900006-07 01:53:32.467 12027 12027 F DEBUG   :     x28 0000007ca13c2c28  x29 0000007c02d886f006-07 01:53:32.467 12027 12027 F DEBUG   :     lr  0000007c02d886f0  sp  0000007c02d886d0  pc  0000007c02d886f0  pst 000000008000100006-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;  // BOOMdelete [] 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;  // BOOMdelete [] 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 finddevice-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 finddevice-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

相关文章:

Android稳定性系列-01-使用 Address Sanitizer检测原生代码中的内存错误

前言想必大家曾经被各种Native Crash折磨过&#xff0c;本地测试没啥问题&#xff0c;一到线上或者自动化测试就出现各种SIGSEGV、SIGABRT、SIGILL、SIGBUS、SIGFPE异常&#xff0c;而且堆栈还是崩溃到libc.so这种&#xff0c;看起来跟我们的代码没啥关系&#xff0c;关键还不好…...

HyperOpt-quniform 范围问题

在使用 quniform 的时候&#xff0c;可能会出现超出指定范围的值&#xff0c;例如对于 GBDT 设置参数空间为 learning_rate:hp.quniform(learning_rate,0.05,2.05,0.2)&#xff0c;但是仍然会报错 ValueError: learning_rate must be greater than 0 but was 0.0&#xff0c;但…...

Pycharm搭建一个Django项目

File->new project 点击create&#xff0c; 等待一下即可 查看安装 Django 版本&#xff1a; 在 Pycharm 底部选择 Terminal 然后在里面输入&#xff1a;python -m django --version 启动项目&#xff1a; 在 Terminal 里面输入: python manage.py runserver 查看文件目…...

浅析前端工程化中的一部曲——模块化

在日益复杂和多元的 Web 业务背景下&#xff0c;前端工程化经常会被提及。工程化的目的是高性能、稳定性、可用性、可维护性、高效协同&#xff0c;只要是以这几个角度为目标所做的操作&#xff0c;都可成为工程化的一部分。工程化是软件工程中的一种思想&#xff0c;当下的工程…...

新版bing(集成ChatGPT)申请通过后在谷歌浏览器(Chrome)上的使用方法

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,科大讯飞比赛第三名,CCF比赛第四名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...

Time-distributed 的理解

前言 今天看到论文中用到 Time-distributed CNN&#xff0c;第一次见到 Time-distributed&#xff0c;不理解是什么含义&#xff0c;看到代码实现也很懵。不管什么网络结构&#xff0c;外面都能套一个TimeDistributed。看了几个博客&#xff0c;还是不明白&#xff0c;问了问C…...

matlab 计算矩阵的Moore-Penrose 伪逆

目录 一、Moore-Penrose 伪逆1、主要函数2、输入输出参数二、代码示例使用伪逆求解线性方程组一、Moore-Penrose 伪逆 Moore-Penrose 伪逆是一种矩阵,可在不存在逆矩阵的情况下作为逆矩阵的部分替代。此矩阵常被用于求解没有唯一解或有许多解的线性方程组。    对于任何矩阵…...

简历制作方面的经验与建议

专栏推荐:2023 数字IC设计秋招复盘——数十家公司笔试题、面试实录 专栏首页:2023 数字IC设计秋招复盘——数十家公司笔试题、面试实录 专栏内容: 笔试复盘篇 2023秋招过程中整理的笔试题,来源包括我自己求职笔试以及整理其他同学的笔试。包含华为、中兴、联发科、AMD、大…...

C语言--static、const、volatile关键字

Static static修饰局部变量改变了变量的生命周期&#xff0c;让静态局部变量出了作用域依然存在&#xff0c;到程序结束&#xff0c;生命周期才结束。 static 修饰局部变量 改变局部变量的生命周期&#xff0c;本质上是改变了局部变量的存储位置&#xff0c;让局部变量不再是…...

Rust学习入门--【18】Rust结构体

系列文章目录 Rust 语言是一种高效、可靠的通用高级语言&#xff0c;效率可以媲美 C / C 。本系列文件记录博主自学Rust的过程。欢迎大家一同学习。 Rust学习入门–【1】引言 Rust学习入门–【2】Rust 开发环境配置 Rust学习入门–【3】Cargo介绍 Rust学习入门–【4】Rust 输…...

LeetCode142 环形链表Ⅱ

题目&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评…...

JavaScript刷LeetCode拿offer-高频链表题

首先需要了解链表的概念 先把 next 记录下来 无论是插入&#xff0c;删除&#xff0c;还是翻转等等操作&#xff0c;先把 next 指针用临时变量保存起来&#xff0c;这可以解决 90% 重组链表中指向出错的问题&#xff0c; 如果不知道什么时候需要用到守卫&#xff0c;那就都用…...

linux系统编程2--网络编程

在linux系统编程中网络编程是使用socket&#xff08;套接字&#xff09;&#xff0c;socket这个词可以表示很多概念&#xff1a;在TCP/IP协议中&#xff0c;“IP地址TCP或UDP端口号”唯一标识网络通讯中的一个进程&#xff0c;“IP地址端口号”就称为socket。在TCP协议中&#…...

Allegro如何重命名光绘操作指导

Allegro如何重命名光绘操作指导 在做PCB设计的时候,光绘设置是输出生产文件必要的流程,设置好光绘之后,如何对光绘重新命名,如下图 如何把L1改成TOP,L6改成BOTTOM,具体操作步骤如下 点击Manufacture选择Artwork...

[PMLR 2018] Hyperbolic entailment cones for learning hierarchical embeddings

Contents IntroductionEntailment Cones in the Poincar BallConvex cones in a complete Riemannian manifoldAngular cones in the Poincar ballfour intuitive propertiesClosed form expression of the optimal ψ \psi...

2023春季露营投影怎么选?轻薄投影极米Z6X Pro值得推荐

近年来&#xff0c;露营经济在多重因素的共同助推下快速发展&#xff0c;精致露营的攻略开始占据小红书、微博、朋友圈等各类社交平台&#xff0c;吸引着更多用户种草并加入到露营大军中&#xff0c;而露营经济的强势“破圈”给家用智能投影带来了更多的发展契机。凭借着小巧的…...

收藏,核心期刊的投稿、审稿、出刊流程详解

学术期刊论文&#xff08;核心和普刊&#xff09;的发表流程总的来说其实是一样的&#xff0c;整个流程包括&#xff1a;1写作-2选择刊物-3投稿-4审稿-5返修或拒稿-6录用-7出刊-8上网检索。 其中1和2其实顺序是可以调换的&#xff0c;可以选择好刊物再写作&#xff0c;根据刊物…...

JVM类加载子系统

1、类加载子系统在内存结构中所处的位置通过内存结构图&#xff0c;我们先知道类加载子系统所处的位置&#xff0c;做到心中有图。2、类加载器作用类加载器子系统负责从文件系统或者网络中加载Class文件&#xff0c;class文件在文件开头有特定的文件标识。ClassLoader只负责cla…...

摄像头的镜头的几个知识点

1、镜头的组成及镜片的固定方式 摄像头的镜头结构主要分为镜身&#xff0c;透镜&#xff0c;变焦环&#xff0c;对焦环&#xff0c;光圈叶片&#xff0c;部分还有防抖系统&#xff0e;其中最重要的就是透镜&#xff0c;也叫镜片。镜片的主要原料是光学玻璃&#xff0c;玻璃&…...

分布式-分布式存储笔记

读写分离 什么时候需要读写分离 互联网大部分业务场景都是读多写少的&#xff0c;读和写的请求对比可能差了不止一个数量级。为了不让数据库的读成为业务瓶颈&#xff0c;同时也为了保证写库的成功率&#xff0c;一般会采用读写分离的技术来保证。 读写分离的实现是把访问的压…...

第十三届蓝桥杯国赛 C++ C 组 Java A 组 C 组 Python C 组 E 题——斐波那契数组(三语言代码AC)

目录1.斐波那契数组1.题目描述2.输入格式3.输出格式4.样例输入5.样例输出6.数据范围7.原题链接2.解题思路3.Ac_code1.Java2.C3.Python1.斐波那契数组 1.题目描述 如果数组 A(a0,a1,⋯.an−1)A(a_0,a_1,⋯.a_{n-1})A(a0​,a1​,⋯.an−1​)满足以下条件, 就说它是一个斐波那契…...

多因子模型(MFM)

多因子模型&#xff08;Muiti-Factor M: MFM&#xff09;因子投资基础CAPM (资本资产定价模型)APT套利定价理论截面数据 & 时间序列数据 & 面板数据定价误差 α\alphaαalpha 出现的原因线性多因子模型Fama-French三因子模型三因子的计算公式利用alpha大小进行购买股票…...

django项目实战一(django+bootstrap实现增删改查)

目录 一、创建django项目 二、修改默认配置 三、配置数据库连接 四、创建表结构 五、在app当中创建静态文件 六、页面实战-部门管理 1、实现一个部门列表页面 2、实现新增部门页面 3、实现删除部门 4、实现部门编辑功能 七、模版的继承 1、创建模板layout.html 1&…...

graphsage解读

传统的图方法都是直推式(transductive)的&#xff0c;学习到的是结构固定的图模型&#xff0c;一旦有新的节点加入&#xff0c;便需要重新训练整个图网络&#xff0c;泛化性不强。GraphSAGE是归纳式(inductive)的&#xff0c;它学习一种映射&#xff1a;通过采样和聚合邻居节点…...

一文带你读懂Dockerfile

目录 一、概述 二、DockerFile构建过程解析 &#xff08;一&#xff09;Dockerfile内容基础知识 &#xff08;二&#xff09;Docker执行Dockerfile的大致流程 &#xff08;三&#xff09;总结 三、DockerFile常用保留字指令 四、案例 &#xff08;一&#xff09;自定义…...

用python实现对AES加密的视频数据流解密

密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法。 在做网络爬虫的时候,会遇到经过AES加密的数据,可以使用python来进行解密。 在做爬虫的时候,通常可以找到一个key,这个key是一个十六进制的一串字符,这传字符是解密的关键。所以对于…...

网络高可用方案

目录 1. 网络高可用 2. 高可用方案设计 2.1 方案一 堆叠 ha负载均衡模式 2.2 方案二 OSPF ha负载均衡模式 3. 高可用保障 1. 网络高可用 网络高可用&#xff0c;是指对于网络的核心部分或设备在设计上考虑冗余和备份&#xff0c;减少单点故障对整个网络的影响。其设计应…...

简单的认识 Vue(vue-cli安装、node安装、开发者工具)

Vue1、Vue 与其他框架的对比及特点1.1 Vue.js 是什么1.2 作者1.3 作用1.4 Vue 与其他框架的对比2、安装 Vue 的方法2.1 CDN 引入2.2 脚手架工具2.3 vue 开发者工具安装3、创建第一个实例4、理解 Vue 的 MVVM 模式5、数据双向绑定5.1 感受响应式实验总结1、Vue 与其他框架的对比…...

如何写一个 things3 client

Things3[1] 是一款苹果生态内的任务管理软件&#xff0c;是一家德国公司做的&#xff0c;非常好用。我前后尝试了众多任务管理软件&#xff0c;最终选定 things3&#xff0c;以后有机会会写文章介绍我是如何用 things3 来管理我的日常任务。本文主要介绍欧神写的 tli[2] 工具来…...

人工智能原理复习 | 命题逻辑和谓词演算

文章目录 一、前言二、命题逻辑三、谓词逻辑CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、前言 数理逻辑思想的起源:莱布尼茨之梦。古典数理逻辑主要包括两部分:命题逻辑和谓词逻辑,命题逻辑又是谓词逻辑的一种简单情形。 逻辑研究的基本内容: 语法。语言部分:基…...