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

news2024/9/20 22:49:20

前言

想必大家曾经被各种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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/358718.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark3每个job之间任务间隔过长

公司的跑批引擎从impala改成Spark3已经有一个多月了。 不得不说&#xff0c;跑批稳定了好多。资源控制有相对稳定了很多。Spark3比CDH的hive on spark2.4.0要快不少。AQE和CBO真的挺强的。但是使用中发现了一个很奇怪的事情。这个问题在网上搜过&#xff0c;并没有实际解决。 当…

【机器学习】决策树-ID3算法

1.ID3算法 ID3算法利用信息增益进行特征的选择进行树的构建。信息熵的取值范围为0~1&#xff0c;值越大&#xff0c;越不纯&#xff0c;相反值越小&#xff0c;代表集合纯度越高。信息增益反映的是给定条件后不确定性减少的程度。每一次对决策树进行分叉选取属性的时候&#x…

CANopen概念总结、心得体会

NMT网络管理报文&#xff1a; NMT 主机和 NMT 从机之间通讯的报文就称为 NMT 网络管理报文。常见报文说明&#xff1a; 0101---------------网络报文发送Nmt_Start_Node&#xff0c;让电机进入OP模式(此时还不会发送同步信号) setState(d, Operational)------------------开启…

拳打DALL-E 2脚踢Imagen,谷歌最新Muse模型刷新文本图像合成排行榜

原文链接&#xff1a;https://www.techbeat.net/article-info?id4501 作者&#xff1a;seven_ 论文链接&#xff1a; https://arxiv.org/abs/2301.00704 项目主页&#xff1a; https://muse-model.github.io/ 近期火爆AI社区的文本图像合成模型家族又添新成员了&#xff0c;之…

网络计划--时间参数的计算和优化

根据网络图的基本概念和原则绘制出网络图之后&#xff0c;我们可以计算网络图中有关的时间参数&#xff0c;主要目的是找出关键路线&#xff0c;为网络计划的优化、调整和执行提供明确的时间概念。如下图中从始点①到终点⑧共有4条路线&#xff0c;可以分别计算出每条路线所需的…

基于Hive的河北新冠确诊人数分析系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

通过官网怎么查找联盟申请链接

欢迎关注勤于奋每天12点准时更新国外LEAD相关技术今天还是来聊聊这个问题吧&#xff0c;很多人问我这个问题&#xff0c;我觉得这个都不是啥多难的技术&#xff0c;用点心就能找到。最简单的办法就是通过浏览器去搜索&#xff0c;比如通过google 搜索,就能找到一些信息&#xf…

第三届无线通信AI大赛分享交流会暨颁奖典礼顺利举办,大赛圆满收官

2月16日&#xff0c;第三届无线通信AI大赛分享交流会暨颁奖典礼在北京顺利举行&#xff0c;宣告大赛圆满收官。 分享交流会暨颁奖典礼以线上线下结合的形式展开&#xff0c;邀请无线通信领域的多位专家、学者与「基于AI的信道估计与信道状态信息反馈联合设计」、「基于AI的高精…

将二进制文件作为目标文件中的一个段

将二进制文件作为目标文件中的一个段 python 生成2进制文件 import sysdef testFile(fileName):# --with open(fileName, modewb) as hexFile:bBuf bytes.fromhex("0123456789abcdef")print("bBuf:",bBuf.hex())len hexFile.write(bBuf)print ("l…

Vue3搭建记录

一、初始化项目&#xff1a;项目名称vue3-element-admin npm init vitelatest vue3-element-admin --template vue-ts 二、整合Element-Plus 1.本地安装Element Plus和图标组件 npm install element-plus npm install element-plus/icons-vue 2.全局注册组件 // main.ts imp…

【C#】async关键字修饰后有无await的影响

文章目录测试总结拓展&#xff1a;js的async await问题参考测试 来自微软官网的说法&#xff1a; 异步方法通常包含 await 运算符的一个或多个匹配项&#xff0c;但缺少 await 表达式不会导致编译器错误。 如果异步方法未使用 await 运算符标记悬挂点&#xff0c;则该方法将作…

RK3568工业开发板工控板说明

说明HW356X-GKA是采用中高端的通用型 SOC&#xff0c;一款基于Rockchip公司RK3568处理器的工控主板。主板标配处理器为Cortex-A55四核&#xff0c;最高主频2GHz的RK3568处理器&#xff0c;内置4GB DDR4内存(最大8GB)&#xff0c;32GB eMMC存储。集成4核 arm架构 A55 处理器和Ma…

记录使用ROS驱动USB相机

参考https://blog.csdn.net/weixin_48657767/article/details/126054121?spm1001.2014.3001.5502cmake编译时有bug&#xff0c;缺包&#xff0c;安装对应的包sudo apt-get install ros-melodic&#xff08;对应ros版本&#xff09;-****&#xff08;对应包名&#xff0c;下划线…

OpenGL学习日记之光照计算

引言 现实生活中的光照极其复杂&#xff0c;而且会收到很多因素的影响&#xff0c;是我们当前计算机的算力无法模拟的。因此我们会根据一些简化的模型来模拟现实光照&#xff0c;这样在可以模拟出近似的光照感受&#xff0c;但是又没有那么复杂的计算。 常用的光照模型有&…

27 pandas 数据透视

文章目录pivot_table 函数1、index需要聚合的列名&#xff0c;默认情况下聚合所有数据值的列2、values在结果透视的行上进行分组的列名或其它分组键【就是透视表里显示的列】3、columns在结果透视表的列上进行分组的列名或其它分组键4、Aggfunc聚合函数或函数列表&#xff08;默…

【1】linux命令每日分享——mkdir

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…

【Spring】难理解的Aop编程 | 入门?

作者&#xff1a;狮子也疯狂 专栏&#xff1a;《spring开发》 坚持做好每一步&#xff0c;幸运之神自然会驾凌在你的身上 目录一. &#x1f981; 前言二. &#x1f981; 常见概念2.1 常见术语2.2 AOP入门Ⅰ. &#x1f407; 功能场景Ⅱ. &#x1f407; 实现过程2.3 通知类型Ⅰ.…

XXL-JOB分布式任务调度框架(三)-集群部署

文章目录 1.引言2.集群服务启动3.反向代理4.总结1.引言 XXL-JOB有中心化的思想,一旦调度中心挂机会导致整体不可使用,所以要引入集群。 需要考虑点: db配置保持一致登录账号配置保持一致集群机器时钟保持一致(单机集群可忽视)2.集群服务启动 在是在同一台机器中,并且在…

wav2vec 2.0:一种自监督的语音识别方法

总体框架&#xff1a; 主要分为2个大模块&#xff1a;1:语音特征提取模块 2:语音特征向量融合模块 1:特征提取模块 输入&#xff1a;音频 输出&#xff1a;音频特征向量 过程&#xff1a; 1&#xff09;跟具体采样率有关&#xff0c;如果一段1S的音频&#xff0c;采样率是1…

踔厉奋发·勇毅前行 | 2023广和通中国区代理商大会成功召开

2月16日&#xff0c;以“踔厉奋发 勇毅前行”为主题的2023广和通中国区代理商大会暨颁奖晚宴于深圳盛大开启并顺利落幕。广和通CEO应凌鹏、中国区销售部副总裁陈绮华等高层领导出席本次会议并发表演讲&#xff0c;与来自全国各地的代理商合作伙伴齐聚一堂&#xff0c;共话商机。…