I have a large C++ application with some Objective-C mixed in, building with XCode 5. One view in the app has a list of items. Dragging and dropping the list items will work fine for 5 or 10 or 50 times, but eventually the app will crash during the dragging. It never crashes when running from XCode (release or debug builds). It doesn't crash when I run the debug build externally. It only crashes running the release build externally.
Here's the snippet that begins the drag operation (the crash occurs before returning from dragImage):
// start drag
m_bDragging = true;
[[pHost getView]
dragImage:pDragImage
at:ptOffset.getNSPoint()
offset:NSZeroSize
event:pEvent
pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
source:[pHost getView]
slideBack:YES];
m_bDragging = false;
[pHost getView] returns an NSView member variable pointer. It doesn't improve the behavior to provide a NULL for dragImage and event. The pasteboard has a list of file names related to the list items.
Here is a typical crash report (which always have a CFSetGetValue in them):
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000025900000100
VM Regions Near 0x25900000100:
CG shared images 00000001c871f000-00000001c8727000 [ 32K] r--/r-- SM=SHM
-->
JS JIT generated code 00002ece70800000-00002ece70801000 [ 4K] ---/rwx SM=NUL
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 com.apple.CoreFoundation 0x00007fff9a8c06a9 CFSetGetValue + 25
1 com.apple.CoreFoundation 0x00007fff9a8d81df __CFRunLoopFindMode + 223
2 com.apple.CoreFoundation 0x00007fff9a902a39 CFRunLoopAddTimer + 153
3 com.apple.HIServices 0x00007fff9265bf15 StartIPCPing + 166
4 com.apple.HIToolbox 0x00007fff986956bf __DragInfoPtrSetValueForKey + 160
5 com.apple.HIToolbox 0x00007fff98695616 __CoreDragSetValueForKey + 52
6 com.apple.AppKit 0x00007fff905c968d __50-[NSDragDestination _resetUpdateDraggingItemTimer]_block_invoke + 164
7 libdispatch.dylib 0x00007fff96beb1bb _dispatch_call_block_and_release + 12
8 libdispatch.dylib 0x00007fff96be828d _dispatch_client_callout + 8
9 libdispatch.dylib 0x00007fff96bf0433 _dispatch_after_timer_callback + 77
10 libdispatch.dylib 0x00007fff96be828d _dispatch_client_callout + 8
11 libdispatch.dylib 0x00007fff96bea885 _dispatch_source_invoke + 413
12 libdispatch.dylib 0x00007fff96befe97 _dispatch_main_queue_callback_4CF + 244
13 com.apple.CoreFoundation 0x00007fff9a9404f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
14 com.apple.CoreFoundation 0x00007fff9a8fb714 __CFRunLoopRun + 1636
15 com.apple.CoreFoundation 0x00007fff9a8fae75 CFRunLoopRunSpecific + 309
16 com.apple.HIToolbox 0x00007fff98634a0d RunCurrentEventLoopInMode + 226
17 com.apple.HIToolbox 0x00007fff986347b7 ReceiveNextEventCommon + 479
18 com.apple.HIToolbox 0x00007fff986345bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
19 com.apple.AppKit 0x00007fff902bb24e _DPSNextEvent + 1434
20 com.apple.AppKit 0x00007fff902ba89b -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
21 com.apple.AppKit 0x00007fff905c9170 NSCoreDragBlockingProc + 107
22 com.apple.HIServices 0x00007fff9265a230 SampleMouseAndKeyboard + 102
23 com.apple.HIServices 0x00007fff92659f50 DragInApplication + 50
24 com.apple.HIServices 0x00007fff92659177 CoreDragStartDragging + 519
25 com.apple.AppKit 0x00007fff905c5a54 -[NSCoreDragManager _dragUntilMouseUp:accepted:] + 862
26 com.apple.AppKit 0x00007fff9077d3a4 -[NSCoreDragManager dragImage:fromWindow:at:offset:event:pasteboard:source:slideBack:] + 1355
27 com.apple.AppKit 0x00007fff90a6385b -[NSWindow(NSDrag) d
Another crash log started like this:
2014-09-04 19:47:59.659 myApp[47690:507] -[__NSCFNumber member:]: unrecognized selector sent to instance 0x5907
2014-09-04 19:47:59.687 myApp[47690:507] An uncaught exception was raised
2014-09-04 19:47:59.688 myApp[47690:507] -[__NSCFNumber member:]: unrecognized selector sent to instance 0x5907
2014-09-04 19:47:59.688 myApp[47690:507] (
0 CoreFoundation 0x00007fff9a9d925c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff92958e75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff9a9dc12d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff9a937272 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff9a936df8 _CF_forwarding_prep_0 + 120
5 CoreFoundation 0x00007fff9a8c0721 CFSetGetValue + 145
I'm out of ideas. Any help would be appreciated, thanks.
This is a memory management bug in your code. The second crash log shows a message -member:
was sent to an object that doesn't respond to it (an NSNumber), which strongly suggests the target of the message was supposed to be a class that does respond to -member:
. This is a big clue as I'll bet that's your own code. Somewhere along the line, you're trying to send a message to an object after it's already been released. Maybe you forgot to retain the dragged thing somewhere? Maybe you overreleased (if you're not using ARC or garbage collection)? Do you have a dangling reference that you didn't nil out? Dunno.
The tool you should be using is Instruments, with the Zombies instrument. Run the application, make it crash, then let Instruments flag the point wherein you "sent a message to a zombie object" (in this case, the instrument doesn't actually release objects but rather keeps them around and marks them as "zombies" - undead objects - and watches for messages sent to objects that should have been deallocated after their retain count reached zero). Click the arrow in the popover message and pay very close attention to that object's entire lifetime (in terms of where it was created and all retain/release messages sent and from where). This is the only solid way of tracking down a bug of this nature: get it to fail while running under the Zombies instrument in Instruments.