内存不对齐iOS

时间:2013-09-13 06:49:43

标签: ios objective-c runtime rapidjson

我遇到了以下崩溃报告:

Date/Time:       2013-09-12 22:39:54 +0000
OS Version:      iPhone OS 6.1.3 (10B329)
Report Version:  104

Exception Type:  SIGSEGV
Exception Codes: SEGV_ACCERR at 0xa0000008
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                     0x39a3c564 _cache_getImp + 4
1   libobjc.A.dylib                     0x39a3e1d7 class_respondsToSelector + 31
2   CoreFoundation                      0x31b96605 objectIsKindOfClass + 37
3   CoreFoundation                      0x31b9635d __handleUncaughtException + 69
4   libobjc.A.dylib                     0x39a41a65 _objc_terminate() + 129
5   libc++abi.dylib                     0x3948e07b safe_handler_caller(void (*)()) + 79
6   libc++abi.dylib                     0x3948e114 std::terminate() + 20
7   libc++abi.dylib                     0x3948f599 __cxa_current_exception_type + 1
8   libobjc.A.dylib                     0x39a419d1 objc_exception_rethrow + 13
9   CoreFoundation                      0x31adcf21 CFRunLoopRunSpecific + 457
10  CoreFoundation                      0x31adcd49 CFRunLoopRunInMode + 105
11  GraphicsServices                    0x356a82eb GSEventRunModal + 75
12  UIKit                               0x339f2301 UIApplicationMain + 1121
13  Our App                             0x0003bc27 main (main.m:15)

在尝试修复导致此错误的错误之后,我不断地从PLCrashReporter(来自beta测试人员的adhoc版本)一次又一次地收到此崩溃日志。不同的异常代码从SIGSEGV / SEGV_ACCERR到SIGBUS / BUS_ADRALN到EXC_BAD_ACCESS / KERN_INVALID_ADDRESS不等

我正在使用iOS上的rapidjson library(armv7和armv7s)和here (#8)所述的填充修复,我使用objective-c运行时函数在运行时添加方法实现(使用{{1 }})。

我们的代码库主要存在Objective-C代码,包含一些Obj-C ++和一些C代码。内存管理由ARC完成,除了手动处理的Obj-C ++和C部分。我查看了每个malloc / free调用,并且我广泛使用了libgmalloc来确定内存问题但是没有什么对我来说似乎不正确。

我无法自己重现此崩溃日志,而不是在调试或发布模式下,但我们的测试版测试人员偶尔会向我发送此崩溃日志(约50次运行中的1次)。由于我们的产品(希望如此)很快就会在很多iOS设备上运行,这不是我们可以解决的问题。

在阅读了大量内存管理文章之后,我怀疑这个问题是由内存不对齐引起的。因此我怀疑rapidjson是导致这个bug的原因。我对iOS / armv7上的内存对齐缺乏了解不允许我修复此崩溃日志。有人可以在iOS上更多地解释这个主题吗?或者我在错误的地方寻找并且这是另一个记忆问题吗? 我希望有人能指出我正确的方向。

如果需要更多信息,我很乐意提供。 注意:我不是在寻找使用JSONKit或其他库来替换rapidjson的答案。谢谢:))

2 个答案:

答案 0 :(得分:2)

此问题之前已在此处解决:https://devforums.apple.com/message/807860

简而言之,原始的Objective-C异常在未被捕获的异常处理程序中被解除引用之前已经被释放(例如,通过自动释放池)。因此,__ handleleUncaughtException()取消引用一个现在死的指针,你会在异常处理程序中看到崩溃。

答案 1 :(得分:1)

首先,地址0xa0000008看起来没有错位,SEGV_ACCERR并不意味着对齐问题,而是内存访问权限问题(来自sys / signal.h):

#define SEGV_ACCERR     2       /* [XSI] invalid permission for mapped object */

考虑到你正在使用class_addMethod()并且崩溃在_cache_getImp()中,这是检索方法的一部分,我毫无根据的怀疑是你传递了一些无效的指针class_addMethod(),或稍后覆盖该信息。

要检查的是你是使用全局变量还是malloc() ed内存,因为运行时函数不会为你复制。

其次,您看到的崩溃是次要的,您在运行顶级异常处理程序时崩溃,该异常处理程序已经从先前的异常中终止(_objc_terminate())您的程序,但在这种情况下,它是'不是Unix信号,而是Objective-C异常:objc_exception_rethrow()

所以你可能需要首先找出主要错误,例如从异常的日志中得出(在许多情况下只是回溯是不够的。)