#2002 SIGSEGV(SEGV_MAPERR)

本文介绍了在遇到Android应用崩溃错误#2002 SIGSEGV(SEGV_MAPERR)时的排查过程,涉及libart.so库中的异常堆栈。问题可能与libart.so中的内存管理及并发复制垃圾收集有关。解决方案包括检查并清理build.gradle文件中的.so库引用,删除不必要的jnilibs和libs目录下的.so文件,以及调整sourceset配置。
部署运行你感兴趣的模型镜像

遇到这个问题

00 pc 00000000000f8ea4 /apex/com.android.runtime/lib64/libart.so [arm64-v8a::691979e9d66dfedf3fd32d27da323a02]

2

#01 pc 00000000000e8a38 /apex/com.android.runtime/lib64/libart.so [arm64-v8a::691979e9d66dfedf3fd32d27da323a02]

3

#02 pc 00000000000d6d34 /apex/com.android.runtime/lib64/libart.so (art::gc::accounting::ModUnionTableReferenceCache::VisitObjects(void (*)(art::mirror::Object*, void*), void*)+228) [arm64-v8a::691979e9d66dfedf3fd32d27da323a02]

4

#03 pc 00000000000e3638 /apex/com.android.runtime/lib64/libart.so (art::gc::collector::ConcurrentCopying::CopyingPhase()+1236) [arm64-v8a::691979e9d66dfedf3fd32d27da323a02]

5

#04 pc 00000000000e14e0 /apex/com.android.runtime/lib64/libart.so (art::gc::collector::ConcurrentCopying::RunPhases()+1148) [arm64-v8a::691979e9d66dfedf3fd32d27da323a02]

6

#05 pc 00000000000ffeb4 /apex/com.android.runtime/lib64/libart.so (art::gc::collector::GarbageCollector::Run(art::gc::GcCause, bool)+288) [arm64-v8a::691979e9d66dfedf3fd32d27da323a02]

7

#06 pc 000000000011f37c /apex/com.android.runtime/lib64/libart.so (art::gc::Heap::CollectGarbageInternal(art::gc::collector::GcType, art::gc::GcCause, bool)+2740) [arm64-v8a::691979e9d66dfedf3fd32d27da323a02]

8

#07 pc 0000000000131b5c /apex/com.android.runtime/lib64/libart.so (art::gc::Heap::ConcurrentGC(art::Thread*, art::gc::GcCause, bool)+124) [arm64-v8a::

用build.gradle 引入 

implementation 。。。。。。。。。。。。。。

把jnilibs和libs下面的.so库删掉 build.gradle下面的 sourceset标签也删了

您可能感兴趣的与本文相关的镜像

GPT-SoVITS

GPT-SoVITS

AI应用

GPT-SoVITS 是一个开源的文本到语音(TTS)和语音转换模型,它结合了 GPT 的生成能力和 SoVITS 的语音转换技术。该项目以其强大的声音克隆能力而闻名,仅需少量语音样本(如5秒)即可实现高质量的即时语音合成,也可通过更长的音频(如1分钟)进行微调以获得更逼真的效果

### SEGV_MAPERR 内存访问异常的定义与触发条件 在 Linux 系统中,`SEGV_MAPERR` 是 `SIGSEGV` 信号的一种子类型,表示进程尝试访问一个未映射的虚拟内存地址。当 CPU 的 MMU(内存管理单元)在进行虚拟地址到物理地址转换时,发现该虚拟地址没有对应的页表项(即 `pgd` 或 `pte` 为零),则会触发缺页异常,并最终导致 `SEGV_MAPERR` 错误[^2]。 这种情况通常发生在访问一个完全未被映射的地址空间,例如访问一个未初始化的指针或访问超出进程地址空间的地址。 ### 用户空间中的 SEGV_MAPERR 异常 在用户空间程序中,如果访问的虚拟地址未被映射到任何物理页,则会触发 `SEGV_MAPERR`。例如以下代码: ```c #include <stdio.h> int main() { int *ptr = (int *)0x12345678; *ptr = 0; // 触发 SEGV_MAPERR return 0; } ``` 当程序运行时访问该地址,MMU 无法找到对应的页表项,导致缺页异常。如果异常处理程序无法修复(如缺页是由懒加载引起的情况),则内核将向进程发送 `SIGSEGV` 信号,并设置 `si_code` 为 `SEGV_MAPERR`,表示访问的地址从未被映射[^3]。 ### 内核空间中的 SEGV_MAPERR 异常 在内核中,某些情况下也会发生 `SEGV_MAPERR` 异常,尤其是在使用 `vmalloc` 分配的虚拟地址空间中。`vmalloc` 分配的地址虽然在虚拟地址空间中存在,但如果没有建立对应的页表项,访问这些地址同样会导致缺页异常并触发 `SEGV_MAPERR`。 例如,当某个模块访问了一个尚未映射的 `vmalloc` 区域,或访问了一个已经释放但未更新页表的区域时,就会出现此类异常。由于 `vmalloc` 的页表项保存在 `init_mm` 结构中,因此可以通过检查 `init_mm` 的页表结构来定位异常地址的来源[^1]。 ### 异常诊断与调试方法 在分析 `SEGV_MAPERR` 异常时,可以结合内核日志和 GDB 工具进行调试。例如,内核日志中可能会显示异常地址及其对应的页表项内容: ``` [153780.207183] [d8660000] *pgd=00000000 ``` 上述日志表明地址 `0xd8660000` 对应的页目录项为 `0x00000000`,说明该地址未被映射,问题由此产生[^2]。 在用户空间程序中,使用 GDB 加载 core dump 文件后,可以通过以下命令查看异常发生时的堆栈信息和寄存器状态: ```gdb (gdb) bt (gdb) info registers ``` 这些信息有助于定位访问非法地址的具体代码位置。 ### 示例:内核模块中 vmalloc 地址访问异常 假设某个内核模块使用 `vmalloc` 分配了一块内存,但在释放后仍然尝试访问: ```c void *ptr = vmalloc(4096); vfree(ptr); *((int *)ptr) = 0; // 触发 SEGV_MAPERR ``` 此时访问已释放的 `vmalloc` 地址会导致页表项无效,从而引发缺页异常,并最终触发 `SEGV_MAPERR`。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值