5

我有一组本机代码崩溃,但很少发生,但一直在发生SEGV_MAPERR或SEGV_ACCERR。这些崩溃几乎总是由Crashlytics报告,RAM非常低(通常为1-5%)。 '正常'崩溃(即我调试过的)在RAM中没有模式。内存不足会导致本地代码中出现seg错误?

是否有可能这些崩溃是由低内存条件造成的?这将是什么机制?有什么办法可以判断这些内存是否与低内存相关的崩溃或编程错误(错误地使用指针等)?在很多情况下,崩溃发生在我无法调试的库中,我无法在设备上复制崩溃。

这里的一些崩溃从开发者控制台拉,因为它提供了比Crashlytics更详细一点,在这种情况下跟踪:

********** Crash dump: ********** 
Build fingerprint: 'htc/a32eul_metropcs_us/htc_a32eul:5.1/LMY47O/637541.3:user/release-keys' 
pid: 10902, tid: 10989, name: .xxx.xxxx >>> com.xxx.xxxxx <<< 
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x97f78000 
Stack frame #00 pc 0004cd80 /data/app/xxx.xxx.xxxxx-1/lib/arm/libxxx.so: Routine xxxxxMixerInterleavedFloatOutput at libgcc2.c:? 

********** Crash dump: ********** 
Build fingerprint: 'Xiaomi/land/land:6.0.1/MMB29M/V8.1.1.0.MALMIDI:user/release-keys' 
pid: 2661, tid: 2746, name: .xxx.xxxx >>> com.xxx.xxxx <<< 
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 
Stack frame #00 pc 00016954 /system/lib/libc.so (__memcpy_base+36) 
Stack frame #01 pc 0000b14c /data/app/com.xxx.xxxx-2/lib/arm/libswresample-2.so: Routine ?? 
??:0 
+1

'SEG_MAPERR'通常是由一个错误的指针操作导致的(使用一个悬挂指针,从数组尾部脱落,取消引用NULL)。 'SEG_ACCERR'往往与尝试访问未经授权的内存相关联(例如写入只读页面)。虽然内存不足可能会增加发生这种事情的几率,但根本原因将是代码中的指针操作不正确。 – Peter

回答

6

一般有两种可能性:

  1. 内存不足的情况本身不会以某种方式触发正在运行的应用程序中的段错误。可能发生的情况是,当应用程序要求分配额外的内存时,内存分配请求失败。这是一个明确的记忆条件。据记载,相关系统调用在分配内存时可能会失败。但是经常发生的情况是应用程序没有正确编码以检查失败的内存分配请求,并且出于这个原因而崩溃。在这种情况下,内存不足情况导致应用程序段错误是不正确的,这是一个应用程序错误。

  2. Linux内核overcommits the available memory。因此,当所有可用的RAM耗尽时,内核可能无法选择要杀死的进程。

但是,在OOM杀手闯入的情况下,被选中的受害者以SIGKILL终止。 A SEGFAULT表示应用程序错误。

+0

你确定关于Android的#2。 http://stackoverflow.com/questions/2567683/why-does-my-program-occasionally-segfault-when-out-of-memory-rather-than-throwin似乎认为overcommits可能会导致SEGFAULT。 –

+0

和http://arstechnica.com/civis/viewtopic.php?f=20&t=1240341 –

+0

它是'SIGKILL' [根据这个第一个答案](http://stackoverflow.com/questions/6132333/how-to-检测-外的存储器段错误)。这是有道理的。这里的目标是摆脱这个过程。 'SIGSEGV'是可捕获的,如果被捕获,当信号处理程序返回时,信号会被重新抛出。 'SIGKILL'不可捕捉,并且保证摆脱过程,这是整个目的。 –

相关问题