背景知识
- 地址越界问题是指访问了不合法的地址,导致程序运行出现异常,通常表现为应用崩溃(crash)。其故障原因为释放后使用(use after free)、重复释放(double-free)、栈溢出(stack-overflow)、堆溢出(heap-overflow)等,参考地址越界类问题分析方法。
- 地址越界问题通常表现为应用崩溃闪退(crash),没有显式的故障特征可以直接确定是地址越界问题。地址越界问题判断依据包括:问题多次低概率持续发生,崩溃栈顶无规律,同一个崩溃栈顶源码无规律。
- 地址越界问题分类可以参考地址越界事件介绍。
问题定位
- 查看崩溃堆栈,可以发现每次产生崩溃栈都不一样,无规律,预计发生了地址越界问题。
Process name:com.hx.example
Process life time:8s
Reason:Signal:SIGSEGV(SEGV_MAPERR)@0x00424b7474326a9d
Fault thread info:
Tid:63354, Name:com.hx.example
#00 pc 000000000002b9ec /data/storage/el1/bundle/libs/arm64/libutunnel.so(token_report_handler(int, int, void*)+56)(95e2a68a228022f77283aefa824ad2d9381307a7)
#01 pc 000000000002aab8 /data/storage/el1/bundle/libs/arm64/libutunnel.so(msg_idle_cb(uv_idle_s*)+32)(95e2a68a228022f77283aefa824ad2d9381307a7)
#02 pc 000000000001db98 /system/lib64/platformsdk/libuv.so(uv__run_idle+228)(7f3f0c53ff27176dc061e331a1525b34)
#03 pc 0000000000017000 /system/lib64/platformsdk/libuv.so(uv_run+360)(7f3f0c53ff27176dc061e331a1525b34)
#04 pc 000000000002abd8 /data/storage/el1/bundle/libs/arm64/libutunnel.so(thread_func(void*)+228)(95e2a68a228022f77283aefa824ad2d9381307a7)
#05 pc 00000000001bada8 /system/lib/ld-musl-aarch64.so.1(start+236)(c05a4bdaf3657c3186f06e417c4fa802)
Process name:com.hx.example
Process life time:7s
Reason:Signal:SIGSEGV(SEGV_MAPERR)@0x006b6b5b016cd3c8
Fault thread info:
Tid:44438, Name:com.hx.example
#00 pc 0000000002ee5f88 /system/lib64/platformsdk/libace_compatible.z.so(87e797bd4d27e4b60838ea50d45176d8)
#01 pc 00000000008fd07c /system/lib64/platformsdk/libace_compatible.z.so(OHOS::Ace::TaskExecutorImpl::OnPostTask(std::__h::function<void ()>&&, OHOS::Ace::TaskExecutor::TaskType, unsigned int, std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, OHOS::Ace::PriorityType) const+252)(87e797bd4d27e4b60838ea50d45176d8)
#02 pc 0000000002ee42ac /system/lib64/platformsdk/libace_compatible.z.so(OHOS::Ace::Framework::JsiXComponentBridge::~JsiXComponentBridge()+272)(87e797bd4d27e4b60838ea50d45176d8)
#03 pc 0000000002ee4410 /system/lib64/platformsdk/libace_compatible.z.so(OHOS::Ace::Framework::JsiXComponentBridge::~JsiXComponentBridge()+16)(87e797bd4d27e4b60838ea50d45176d8)
- 地址越界问题可以通过使用HWAsan检测内存错误等工具检测出。
- 开发态配置好HWAsan后,调试当前应用。当程序出现内存错误时,弹出HWAsan log信息,点击信息中的链接即可跳转至引起内存错误的代码处,以下示例可供参考。
Module name:com.hx.example
Version:1.0.0
Pid:36316
Uid:20020251
Reason:use-after-free
==appspawn==36316==ERROR: HWAddressSanitizer: tag-mismatch on address 0xXXXX at pc 0x0069136867e4
READ of size 4 at 0xXXXX tags: c4/26 (ptr/mem) in thread T0
#0 0x69136867e4 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x67e4) (BuildId: d35146dc167c816454c7e906c4aa5fb00d0f5c7d) <-- 故障链接
#1 0x691368665c (/data/storage/el1/bundle/libs/arm64/libentry.so+0x665c) (BuildId: d35146dc167c816454c7e906c4aa5fb00d0f5c7d)
#2 0x5efeabec44 (/system/lib64/platformsdk/libace_napi.z.so+0x3ec44) (BuildId: 37dfa4be8ab42a21d0511559b6a4b6de) // 错误示例
static int TestUAF()
{
int* a = new int[2]{1, 2};
delete[] a;
int sum = a[0] + a[1]; // 引起内存错误代码行,使用已经被释放的内存
return sum;
}