在Cocoa应用程序中,objc_msgSend()和EXC_BAD_ACCESS是什么意思?

6
一般来说,我们如何避免在Mac应用程序中出现objc_msgSend()崩溃?另外,我们如何避免EXC_BAD_ACCESS崩溃?为什么会出现这种情况?我们如何管理这些错误?它们在我们的应用程序中越来越多,希望能得到指导和帮助。
我们使用的是XCode 3.2.5,项目是一个Cocoa项目,使用Objective-C语言。我们的Web服务是一个由IIS提供支持的ASP.Net网站(可以从中下载/上传XML文件和图像)。
我们正在开发一款Mac的Cocoa应用程序,在启动应用程序的十次尝试中,有两次会出现这种情况。这个应用程序有一个素描应用程序,当我们运行应用程序时,它只会在1分钟内冻结并崩溃,而不做任何事情。这个应用程序的一些功能包括:
- 从Web上下载XML并在我们的应用程序中解释 - 登录Web服务 - 有一个素描板 - 有一个计时器 - 拖放功能 - 上传XML数据 - 下载图像并在我们的应用程序中显示
崩溃并不限于应用程序启动后。有时,在操作程序时,例如拖放、下载数据集以及在我们的Mac应用程序中执行添加/编辑/删除功能时,应用程序也会崩溃。
老实说,我们对这个开发平台和环境还比较新,我们还在学习中。你能在这个问题上给我们指导吗?例如一些资源或提示,告诉我们哪里做错了?非常感谢,并祝大家更加强大。
以下是一个崩溃报告的例子:
Process:         Sketch [63065]
Path:            /Users/william_hooley_27Inch/Desktop/untitled folder/MacGlass.app/Contents/MacOS/Sketch
Identifier:      com.apple.CocoaExamples.Sketch
Version:         1.049 (48.1)
Code Type:       X86 (Native)
Parent Process:  launchd [116]
Date/Time:       2011-04-14 13:12:15.421 +1000
OS Version:      Mac OS X 10.6.5 (10H574)
Report Version:  6
Interval Since Last Report:          714907 sec
Crashes Since Last Report:           17
Per-App Interval Since Last Report:  206437 sec

Per-App Crashes Since Last Report:   5
Anonymous UUID:                     
086C860F-E28E-4256-84F9-9692782AAD01
Exception Type:  EXC_BAD_ACCESS
(SIGBUS) Exception Codes:
KERN_PROTECTION_FAILURE at
0x0000000000000044 Crashed Thread:  0 
Dispatch queue: com.apple.main-thread
Thread 0 Crashed:  Dispatch queue:
com.apple.main-thread 0  
com.apple.AppKit             
0x91a8e6cb
_recursiveInvalidateCachedVisibleRectValue
+ 24 1   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction + 224
2   com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
+ 90 3   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction + 224
4   com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
+ 90 5   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction + 224
6   com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
+ 90 7   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction + 224
8   com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
+ 90 9   com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction + 224
10  com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
+ 90 11  com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction + 224
12  com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
+ 90 13  com.apple.CoreFoundation      0x995f02c0 CFArrayApplyFunction + 224
14  com.apple.AppKit             
0x91a8e70d
_recursiveInvalidateCachedVisibleRectValue
+ 90 15  com.apple.AppKit              0x91a8e2e1 -[NSView _setSuperview:] +
684 16  com.apple.AppKit             
0x91a8db02 -[NSView addSubview:] + 383
17  com.apple.CocoaExamples.Sketch
0x00094cbf -[viewTasksDisplay Appear:]
+ 242 18  com.apple.CocoaExamples.Sketch
0x000c2e8f -[MainWindow
ShowLeftScreen:] + 964 19 
com.apple.CocoaExamples.Sketch
0x0003e301 -[viewOptionMenuItemmouseDown:] + 2055 20 
com.apple.AppKit             
0x91bc6c68 -[NSWindow sendEvent:] +
5549 21  com.apple.AppKit             
0x91adf817 -[NSApplication sendEvent:]
+ 6431 22  com.apple.AppKit              0x91a732a7 -[NSApplication run] + 917
23  com.apple.AppKit             
0x91a6b2d9 NSApplicationMain + 574 24 
com.apple.CocoaExamples.Sketch
0x0001b33e main + 30 25 
com.apple.CocoaExamples.Sketch
0x00001eba start + 54 Thread 1: 
Dispatch queue:
com.apple.libdispatch-manager 0  
libSystem.B.dylib            
0x98002982 kevent + 10 1  
libSystem.B.dylib            
0x9800309c _dispatch_mgr_invoke + 215
2   libSystem.B.dylib            
0x98002559 _dispatch_queue_invoke +
163 3   libSystem.B.dylib            
0x980022fe _dispatch_worker_thread2 +
240 4   libSystem.B.dylib            
0x98001d81 _pthread_wqthread + 390 5  
libSystem.B.dylib            
0x98001bc6 start_wqthread + 30 Thread
2: 0   libSystem.B.dylib            
0x97fdc0fa mach_msg_trap + 10 1  
libSystem.B.dylib            
0x97fdc867 mach_msg + 68 2  
com.apple.CoreFoundation     
0x995f837f __CFRunLoopRun + 2079

另一个崩溃报告:
Date/Time:       2011-04-14 13:27:02
+1000 OS Version:      10.6.5 (Build 10H574) Architecture:    x86_64 Report
Version:  6 Command:         MacGlass
Path:           
/Users/william_hooley_27Inch/Desktop/untitled
folder/MacGlass.app/Contents/MacOS/Sketch
Version:         1.050 (48.1) Parent: 
launchd [116] PID:             63101
Event:           hang Duration:       
3.58s (sampling started after 2 seconds) Steps:           16 (100ms
sampling interval) Pageins:         0
Pageouts:        0 Process:        
Sketch [63101] Path:           
/Users/william_hooley_27Inch/Desktop/untitled
folder/MacGlass.app/Contents/MacOS/Sketch
UID:             501   Thread edef3d4 
DispatchQueue 100   User stack:
    16 start + 54 (in Sketch) [0x1f6a]
      16 main + 30 (in Sketch) [0x1b3ee]
        16 NSApplicationMain + 574 (in AppKit) [0x91a6b2d9]
          16 -[NSApplication run] + 821 (in AppKit) [0x91a73247]
            16 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
+ 156 (in AppKit) [0x91ab0fce]
              16 _DPSNextEvent + 847 (in AppKit) [0x91ab178d]
                16 BlockUntilNextEventMatchingListInMode
+ 81 (in HIToolbox) [0x95bd0bd6]
                  16 ReceiveNextEventCommon + 354 (in
HIToolbox) [0x95bd0d51]
                    16 RunCurrentEventLoopInMode + 392 (in
HIToolbox) [0x95bd0f9c]
                      16 CFRunLoopRunInMode + 97 (in
CoreFoundation) [0x995f7291]
                        16 CFRunLoopRunSpecific + 452 (in
CoreFoundation) [0x995f7464]
                          16 __CFRunLoopRun + 8059 (in CoreFoundation) [0x995f9adb]
                            16 __NSFireTimer + 141 (in Foundation) [0x972c39b0]
                              16 _handleWindowNeedsDisplay + 696 (in AppKit) [0x91adb28a]
                                16 -[NSWindow displayIfNeeded] + 204 (in AppKit) [0x91aa9d40]
                                  16 -[NSView displayIfNeeded] + 818 (in AppKit) [0x91ae0a57]
                                    16 -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:]
+ 4122 (in AppKit) [0x91b801cf]
                                      16 CAViewEndDraw + 134 (in QuartzCore)
[0x961bd926]
                                        16 pthread_cond_wait$UNIX2003 + 73 (in
libSystem.B.dylib) [0x9800b9f8]
                                          16 __semwait_signal + 10 (in
libSystem.B.dylib) [0x9800a0a6]  
Kernel stack:
    15 semaphore_wait_continue + 0 [0x22a3dd]
    1 lo_alltraps + 454 [0x2a08a6]
      1 i386_astintr + 47 [0x2a9a9a]
        1 ast_taken + 247 [0x219107]
          1 bsd_ast + 806 [0x489088]
            1 postsig + 432 [0x4861df]
              1 exit1 + 449 [0x47ab28]
                1 task_terminate_internal + 315
[0x22c56a]

“EXC_BAD_ACCESS”的常见原因是错误的内存管理。您的应用程序使用垃圾收集吗? - user557219
我建议阅读: So you crashed in objc_msgSend() - Christian Beer
6个回答

4
通常这种情况的原因是过度释放对象。如果您使用NSZombieEnabled运行代码,控制台输出应该会给您一个提示去寻找问题所在。
或者,如果这是一个面向10.5或更高版本的Macintosh应用程序,您可以启用垃圾回收,完全不必担心保留和释放。

3
当iOS应用程序在连接调试器的设备上发生此错误时,您可以通过在调试控制台上键入以下内容来找出被调用的选择器:
(gdb) x/s $r1
这有助于我找到一个问题,当加速计仍然将其委托设置为已释放的对象时。也许这些信息对其他人有帮助。

2
我做错了吗? - William Entriken
上面的答案是针对gdb的,但从你的截图中可以清楚地看出你正在使用lldb(自XCode 4.3以来默认的调试器)。有关如何使用lldb的信息可以在此处找到:http://lldb.llvm.org/tutorial.html - emidander
$r1 在我使用 iOS 8 时并非出问题的寄存器。应该随着情况变化查看堆栈跟踪。 - clearlight

2
第二个崩溃报告并不是一个崩溃,而是一个挂起报告。这意味着您的应用程序很慢,而不是崩溃。
总的来说,请阅读并完全理解Cocoa内存管理指南;在内存管理方面犯的错误占据了Cocoa应用程序崩溃的绝大多数原因。该指南可以在此处找到:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html 您还应该能够使用Xcode调试器和Instruments中的Zombies工具收集有关崩溃的更详细信息。

1

我能够使用lldb找到有问题的选择器,但是我的方法与上面回答中使用gdb语法和早期版本的iOS不同(我目前正在使用iOS 8)

我的堆栈跟踪开始如下:

libobjc.A.dylib`objc_msgSend:
0x10c160000:  testq  %rdi, %rdi
0x10c160003:  jle    0x10c160068        ; objc_msgSend + 104
0x10c160005:  movq   (%rdi), %r11
0x10c160008:  movq   %rsi, %r10
0x10c16000b:  andl   0x18(%r11), %r10d  <== EXC_BAD_ACCESS

在lldb提示符下,我执行了以下操作:
(lldb) register read -G s r10
     r10 = "\xffffffc16\xffffffa4\t\x01"  "isKindOfClass:"

0
我刚刚解决了一个 EXC_BAD_ACCESS 在 objc_msgSend 中的问题,通过找到我覆盖字符串结尾的位置,破坏了存储中的对象。

0
对我来说问题在于,我从一个不是 UIAleraction 的选择器中调用了一个 UIAleraction 处理程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接