NSZombie eating my brain!
I've been learning cocoa bindings (I like this voodoo) and have hit a brick wall. I've been asking pythonmac-sig if they've any ideas and they pointed me in the direction of NSZombieEnabled, but i haven't been able to get very far.
I have an NSArray controller with a python object subclassing NSObject. I've put a + button on the gui to add the python object like this:::
def addTriggerModel_(self, sender): # BUTTON
self.setCanAddTriggerModel_(False)
newTriggerModel = scNSDrumTriggerModel.alloc().init()
newTriggerModel.resetWithNodeBusAndInput(node = self.nextNode, bus = self.nextBus, \
input = self.nextInput, sendInfo = self.sendingTriggersToClient)
self.nextNode += 100
self.nextBus += 10
self.nextInput += 1
NSLog("Adding newTriggerModel")
self.triggerArrayController.addObject_(newTriggerModel)
NSLog("Added newTriggerModel")
self.setCanAddTriggerModel_(True)
This works just peachy the first time I do it, but fails on a second addition of the new scNSDrumTriggerModel object. At first I was getting Signal 5/6 errors, then I did:
from PyObjCTools import Signals
Signals.dumpStackOnFatalSignal()
from PyObjCTools import Debugging
Debugging.installVerboseExceptionHandler()
This told me:
NSGenericException - *** Selector 'retain' sent to dealloced instance 0x1147cb0 of class OC_PythonArray
So I turned on NSZombieEnabled and tried running in gdb with a breakpoint on -[_NSZombie retain], but I don't really know what I'm looking for. I'm looking at a lot of hex memory addresses with very little human-readable stuff in there.
I tried setting a breakpoint at (+[OC_PythonArray newWithPythonObject:]) to see perhaps what proxy objects are being instantiated, but I'm clearly in over my depth. The variable corresponding to the pythonObject in OC_PythonArray newWithPythonObject: up there ^ has address 0x0 (Is that a null pointer?) in gdb each time I hit that breakpoint.
When I run malloc_history on the memory address that the NSZombie has, I get this:
malloc_history 506 0x1147cb0
Call [2] [arg=12]: thread_a000ed98 |0x0 | _dyld_start | 0x2414 | 0x3e50 | 0x3db0 | PyRun_SimpleFileExFlags | PyRun_FileExFlags | PyEval_EvalCode | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | PyEval_GetFuncDesc | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | _PyUnicodeUCS2_IsAlpha | PyRun_FileExFlags | PyEval_EvalCode | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | PyEval_GetFuncDesc | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | objc_NSApplicationMain | NSApplicationMain | +[NSBundle(NSNibLoading) loadNibNamed:owner:] | +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] | +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] | loadNib | -[NSKeyedUnarchiver initForReadingWithData:] | _CFPropertyListCreateFromXMLData | parsePListTag | parseDictTag | parseArrayTag | parseDictTag | parseDictTag | _CFKeyedArchiverUIDCreate | _CFRuntimeCreateInstance | CFAllocatorAllocate
Call [4] [arg=0]: thread_a000ed98 |0x0 | _dyld_start | 0x2414 | 0x3e50 | 0x3db0 | PyRun_SimpleFileExFlags | PyRun_FileExFlags | PyEval_EvalCode | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | PyEval_GetFuncDesc | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | _PyUnicodeUCS2_IsAlpha | PyRun_FileExFlags | PyEval_EvalCode | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | PyEval_GetFuncDesc | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | objc_NSApplicationMain | NSApplicationMain | +[NSBundle(NSNibLoading) loadNibNamed:owner:] | +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] | +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] | loadNib | -[NSKeyedUnarchiver dealloc] | _CFRelease | __CFArrayDeallocate | __CFArrayReleaseValues | _CFRelease | __CFDictionaryDeallocate | _CFRelease
Call [2] [arg=12]: thread_a000ed98 |0x0 | _dyld_start | 0x2414 | 0x3e50 | 0x3db0 | PyRun_SimpleFileExFlags | PyRun_FileExFlags | PyEval_EvalCode | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | PyEval_GetFuncDesc | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | _PyUnicodeUCS2_IsAlpha | PyRun_FileExFlags | PyEval_EvalCode | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | PyEval_GetFuncDesc | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | objc_NSApplicationMain | NSApplicationMain | -[NSApplication run] | -[NSApplication sendEvent:] | -[NSWindow sendEvent:] | -[NSControl mouseDown:] | -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] | -[NSCell trackMouse:inRect:ofView:untilMouseUp:] | -[NSCell _sendActionFrom:] | -[NSControl sendAction:to:] | -[NSApplication sendAction:to:from:] | ffi_closure_ASM | ffi_closure_helper_DARWIN | method_stub | PyObject_Call | pysel_call | PyObject_Call | PyFunction_SetClosure | PyEval_EvalCodeEx | PyEval_EvalCode | PyEval_GetFuncDesc | PyEval_GetFuncDesc | PyObject_Call | objcsel_call | PyObjCFFI_Caller | ffi_call | ffi_call_DARWIN | -[NSArrayController _insertObject:atArrangedObjectIndex:objectHandler:] | -[NSArrayController didChangeValuesForArrangedKeys:objectKeys:indexKeys:] | -[NSController _notifyObserversForKeyPath:change:] | -[NSObject(NSKeyValueObservingPrivate) _notifyObserversForKeyPath:change:] | -[NSSelectionBinder observeValueForKeyPath:ofObject:change:context:] | -[NSValueBinder _observeValueForKeyPath:ofObject:context:] | -[NSSelectionBinder _adjustObject:mode:observedController:observedKeyPath:context:editableState:adjustState:] | -[NSSelectionBinder _valueForBindingWithoutResolve:mode:] | -[NSBinder valueForBinding:resolveMarkersToPlaceholders:] | -[NSBinder _valueForKeyPath:ofObject:mode:raisesForNotApplicableKeys:] | -[NSObject(NSKeyValueCoding) valueForKeyPath:] | -[NSArrayController _singleValueForKeyPath:] | -[NSObject(NSKeyValueCoding) valueForKeyPath:] | ffi_closure_ASM | ffi_closure_helper_DARWIN | object_method_valueForKey_ | _NSGetUsingKeyValueGetter | ffi_closure_ASM | ffi_closure_helper_DARWIN | method_stub | depythonify_c_return_value | depythonify_c_value | +[OC_PythonObject wrapPyObject:toId:] | +[OC_PythonArray newWithPythonObject:] | NSAllocateObject | _internal_class_createInstanceFromZone
Here is the bt when gdb hits NSZombie retain.
#0 0x92a43c80 in -[_NSZombie retain] ()
#1 0x9396c690 in -[_NSModelObservingTracker setIndexReferenceModelObjectArr
ay:clearAllModelObjectObserving:] ()
#2 0x93980c54 in -[NSSelectionBinder _adjustObject:mode:observedController:observedKeyPath:context:editableState:adjustState:] ()
#3 0x939499a8 in -[NSValueBinder _observeValueForKeyPath:ofObject:context:] ()
#4 0x939808f4 in -[NSSelectionBinder observeValueForKeyPath:ofObject:change:context:] ()
#5 0x929fcd08 in -[NSObject(NSKeyValueObservingPrivate) _notifyObserversForKeyPath:change:] ()
#6 0x93972608 in -[NSController _notifyObserversForKeyPath:change:] ()
#7 0x9397246c in -[NSArrayController didChangeValuesForArrangedKeys:objectKeys:indexKeys:] ()
#8 0x93bf6c0c in -[NSArrayController _insertObject:atArrangedObjectIndex:objectHandler:] ()
#9 0x005072e8 in _ffi_call_DARWIN () at libffi-src/src/powerpc/darwin.S:119
#10 0x00506f00 in ffi_call (cif=0x1147470, fn=0x800000, rvalue=0x1147470, avalue=0x0) at libffi-src/src/powerpc/ffi_darwin.c:396
#11 0x00513da0 in PyObjCFFI_Caller (aMeth=0x4406b0, self=0x438170, args=0x103b2f0) at Modules/objc/libffi_support.m:1293
#12 0x00526eb0 in objcsel_call (self=0x4406b0, args=0x103b2f0) at Modules/objc/selector.m:516
#13 0x986e88e0 in PyObject_Call ()
#14 0x9874835c in PyEval_GetFuncDesc ()
#15 0x98747d4c in PyEval_GetFuncDesc ()
#16 0x98745414 in PyEval_EvalCode ()
#17 0x987465e4 in PyEval_EvalCodeEx ()
#18 0x986fd530 in PyFunction_SetClosure ()
#19 0x986e88e0 in PyObject_Call ()
#20 0x00527f88 in pysel_call (self=0x40dbe0, args=0x0, kwargs=0x410cf0) at Modules/objc/selector.m:941
#21 0x986e88e0 in PyObject_Call ()
#22 0x00510958 in method_stub (cif=0x1147470, resp=0xbfffc510, args=0xbfffc440, _userdata=0x0) at Modules/objc/libffi_support.m:479
#23 0x00507104 in ffi_closure_helper_DARWIN (closure=0x1147470, rvalue=0xbfffc510, pgr=0x1147470, pfr=0x0) at libffi-src/src/powerpc/ffi_darwin.c:699
#24 0x005073b4 in _ffi_closure_ASM () at darwin_closure.S:92
#25 0x937c1270 in -[NSApplication sendAction:to:from:] ()
#26 0x937c11a4 in -[NSControl sendAction:to:] ()
#27 0x937c1084 in -[NSCell _sendActionFrom:] ()
#28 0x937db09c in -[NSCell trackMouse:inRect:ofView:untilMouseUp:] ()
#29 0x937dac84 in -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] ()
#30 0x937da6a8 in -[NSControl mouseDown:] ()
#31 0x9377beb0 in -[NSWindow sendEvent:] ()
#32 0x93724ef4 in -[NSApplication sendEvent:] ()
#33 0x9371c330 in -[NSApplication run] ()
#34 0x9380ce68 in NSApplicationMain ()
#35 0x010496f4 in objc_NSApplicationMain (self=0x1147470, args=0x90ab1aa0, kwds=0x1147470) at Modules/AppKit/_AppKit.m:129
#36 0x98747c5c in PyEval_GetFuncDesc ()
#37 0x98745414 in PyEval_EvalCode ()
#38 0x987465e4 in PyEval_EvalCodeEx ()
#39 0x98747f90 in PyEval_GetFuncDesc ()
#40 0x98747d34 in PyEval_GetFuncDesc ()
#41 0x98745414 in PyEval_EvalCode ()
#42 0x987465e4 in PyEval_EvalCodeEx ()
#43 0x98742eb8 in PyEval_EvalCode ()
#44 0x9876708c in PyRun_FileExFlags ()
#45 0x9873c210 in _PyUnicodeUCS2_IsAlpha ()
#46 0x98747c5c in PyEval_GetFuncDesc ()
#47 0x98745414 in PyEval_EvalCode ()
#48 0x987465e4 in PyEval_EvalCodeEx ()
#49 0x98747f90 in PyEval_GetFuncDesc ()
#50 0x98747d34 in PyEval_GetFuncDesc ()
#51 0x98745414 in PyEval_EvalCode ()
#52 0x987465e4 in PyEval_EvalCodeEx ()
#53 0x98742eb8 in PyEval_EvalCode ()
#54 0x9876708c in PyRun_FileExFlags ()
#55 0x987660b0 in PyRun_SimpleFileExFlags ()
#56 0x00003db0 in ?? ()
#57 0x00003e50 in ?? ()
#58 0x00002414 in ?? ()
#59 0x8fe01048 in __dyld__dyld_start ()
And here's the trace output in the console when the app just pukes running outside of gdb
Stack trace (most recent call last):
0x00002414 (in Trigger)
0x00003e50 (in Trigger)
0x00003db0 (in Trigger)
_PyRun_SimpleFileExFlags (in Python)
_PyRun_FileExFlags (in Python)
_PyEval_EvalCode (in Python)
_PyEval_EvalCodeEx (in Python)
_PyEval_EvalCode (in Python)
_PyEval_GetFuncDesc (in Python)
_PyEval_GetFuncDesc (in Python)
_PyEval_EvalCodeEx (in Python)
_PyEval_EvalCode (in Python)
_PyEval_GetFuncDesc (in Python)
__PyUnicodeUCS2_IsAlpha (in Python)
_PyRun_FileExFlags (in Python)
_PyEval_EvalCode (in Python)
_PyEval_EvalCodeEx (in Python)
_PyEval_EvalCode (in Python)
_PyEval_GetFuncDesc (in Python)
_PyEval_GetFuncDesc (in Python)
_PyEval_EvalCodeEx (in Python)
_PyEval_EvalCode (in Python)
_PyEval_GetFuncDesc (in Python)
_objc_NSApplicationMain (in _AppKit.so) (_AppKit.m:129)
_NSApplicationMain (in AppKit)
-[NSApplication run] (in AppKit)
-[NSApplication sendEvent:] (in AppKit)
-[NSWindow sendEvent:] (in AppKit)
-[NSControl mouseDown:] (in AppKit)
-[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] (in AppKit)
-[NSCell trackMouse:inRect:ofView:untilMouseUp:] (in AppKit)
-[NSCell _sendActionFrom:] (in AppKit)
-[NSControl sendAction:to:] (in AppKit)
-[NSApplication sendAction:to:from:] (in AppKit)
_ffi_closure_ASM (in _objc.so) (darwin_closure.S:95)
_ffi_closure_helper_DARWIN (in _objc.so) (ffi_darwin.c:703)
_method_stub (in _objc.so) (libffi_support.m:479)
_PyObject_Call (in Python)
_pysel_call (in _objc.so) (selector.m:941)
_PyObject_Call (in Python)
_PyFunction_SetClosure (in Python)
_PyEval_EvalCodeEx (in Python)
_PyEval_EvalCode (in Python)
_PyEval_GetFuncDesc (in Python)
_PyEval_GetFuncDesc (in Python)
_PyObject_Call (in Python)
_objcsel_call (in _objc.so) (selector.m:517)
_PyObjCFFI_Caller (in _objc.so) (libffi_support.m:1300)
_ffi_call (in _objc.so) (ffi_darwin.c:404)
_ffi_call_DARWIN (in _objc.so) (darwin.S:121)
-[NSArrayController _insertObject:atArrangedObjectIndex:objectHandler:] (in AppKit)
-[NSArrayController didChangeValuesForArrangedKeys:objectKeys:indexKeys:] (in AppKit)
-[NSController _notifyObserversForKeyPath:change:] (in AppKit)
-[NSObject(NSKeyValueObservingPrivate) _notifyObserversForKeyPath:change:] (in Foundation)
-[NSSelectionBinder observeValueForKeyPath:ofObject:change:context:] (in AppKit)
-[NSValueBinder _observeValueForKeyPath:ofObject:context:] (in AppKit)
-[NSSelectionBinder _adjustObject:mode:observedController:observedKeyPath:context:editableState:adjustState:] (in AppKit)
-[_NSModelObservingTracker setIndexReferenceModelObjectArray:clearAllModelObjectObserving:] (in AppKit)
-[_NSZombie retain] (in Foundation)
+[NSException raise:format:] (in Foundation)
_NSExceptionHandlerExceptionRaiser (in ExceptionHandling)
2006-04-09 16:13:52.454 Trigger[762] NSGenericException - *** Selector 'retain' sent to dealloced instance 0x1147be0 of class OC_PythonArray.
Break at '-[_NSZombie retain]' to debug.