[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSClassSwapper leaving dangling pointers?

From: Eric Wasylishen
Subject: Re: NSClassSwapper leaving dangling pointers?
Date: Sat, 22 Jun 2013 10:38:26 -0400

Hi Luboš,

I'm not too familiar with nib loading internals, but I will try to take a look. Could you  upload your work in progress code somewhere? (Or do you have any changes to the original Mac source?)

Cool idea to port the unarchiver. :-)


On Jun 21, 2013 11:30 AM, "Luboš Doležel" <address@hidden> wrote:

I'm still working on getting the latest The Unarchiver for OS X <> working under GNUstep/Darling/Linux and I'm seeing crashes after the application's NIB file is loaded.

Now I'm sort of helpless. The crash happens when using the target of a certain NSMenuItem.

You can see an excerpt of the relevant NIB's source here; the NSMenuItem clearly refers to the NSPopUpButtonCell that it is part of:

<object class="NSPopUpButtonCell" key="NSCell" id="824605593">
  <int key="NSCellFlags">-2076180416</int>
  <int key="NSCellFlags2">2048</int>
  <reference key="NSSupport" ref="170887875"/>
  <reference key="NSControlView" ref="790450297"/>
  <int key="NSButtonFlags">109199360</int>
  <int key="NSButtonFlags2">1</int>
  <reference key="NSAlternateImage" ref="538669737"/>
  <string key="NSAlternateContents"/>
  <object class="NSMutableString" key="NSKeyEquivalent">
    <characters key="NS.bytes"/>
  <int key="NSPeriodicDelay">400</int>
  <int key="NSPeriodicInterval">75</int>

  <object class="NSMenuItem" key="NSMenuItem" id="444300673">
   <reference key="NSMenu" ref="552121880"/>
   <string key="NSTitle">dummy</string>
   <string key="NSKeyEquiv"/>
   <int key="NSKeyEquivModMask">1048576</int>
   <int key="NSMnemonicLoc">2147483647</int>
   <int key="NSState">1</int>
   <reference key="NSOnImage" ref="1019969751"/>
   <reference key="NSMixedImage" ref="16787521"/>
   <string key="NSAction">_popUpItemAction:</string>
   <reference key="NSTarget" ref="824605593"/>

(Full code can be found in The Unarchiver's source tarball in MainMenu.nib/designable.nib)

I can see the target being set correctly via -setTarget upon loading:

Breakpoint 3, -[NSMenuItem setTarget:] (self=0x1845808, _cmd=0x7ffff7a51eb0 <.objc_selector_list+176>, anObject=0x1843d58) at NSMenuItem.m:465
465       if (_target == anObject)
(gdb) p anObject
$15 = (id) 0x1843d58
(gdb) p anObject->isa
$16 = (struct objc_class *) 0x7ffff7a6bcc0 <_OBJC_CLASS_NSPopUpButtonCell>


#0  -[NSMenuItem setTarget:] (self=0x189de68, _cmd=0x7ffff79f7ce0 <.objc_selector_list+640>, anObject=0x1429f18) at NSMenuItem.m:465
#1  0x00007ffff745354e in -[NSNibControlConnector establishConnection] (self=0x189de38, _cmd=0x7ffff7afe330 <.objc_selector_list+1232>) at NSBundleAdditions.m:177
#2  0x00007ffff76cfb91 in -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] (self=0x14be778, _cmd=0x7ffff7afdf70 <.objc_selector_list+272>, owner=0xe67488,
    topLevelObjects=0x0) at GSNibLoading.m:1926
#3  0x00007ffff76cff26 in -[NSIBObjectData awakeWithContext:] (self=0x14be778, _cmd=0x7ffff7b1a170 <.objc_selector_list+176>, context=0xcb09f8) at GSNibLoading.m:1982
#4  0x00007ffff771028e in -[GSNibLoader loadModelData:externalNameTable:withZone:] (self=0xde8158, _cmd=0x7ffff7a56260 <.objc_selector_list+224>, data="" context=0xcb09f8,
    zone=0x329060bb38 <default_zone>) at GSNibLoader.m:87
#5  0x00007ffff753f57d in -[NSNib instantiateNibWithExternalNameTable:withZone:] (self=0xecf938, _cmd=0x7ffff79f7b00 <.objc_selector_list+160>, externalNameTable=0xcb09f8,
    zone=0x329060bb38 <default_zone>) at NSNib.m:153
#6  0x00007ffff7453949 in +[NSBundle(NSBundleAdditions) loadNibFile:externalNameTable:withZone:] (self=0x329057f000 <_OBJC_CLASS_NSBundle>,
    _cmd=0x7ffff79f7b20 <.objc_selector_list+192>, fileName=0xf03638, context=0xcb09f8, zone=0x329060bb38 <default_zone>) at NSBundleAdditions.m:236
#7  0x00007ffff7454076 in -[NSBundle(NSBundleAdditions) loadNibFile:externalNameTable:withZone:] (self=0xd406e8, _cmd=0x7ffff79f7b20 <.objc_selector_list+192>, fileName=0xeb5498,
    context=0xcb09f8, zone=0x329060bb38 <default_zone>) at NSBundleAdditions.m:342
#8  0x00007ffff7453b5e in +[NSBundle(NSBundleAdditions) loadNibNamed:owner:] (self=0x329057f000 <_OBJC_CLASS_NSBundle>, _cmd=0x7ffff79db520 <.objc_selector_list+688>,
    aNibName=0xeb5498, owner=0xe67488) at NSBundleAdditions.m:277
#9  0x00007ffff73e2a83 in NSApplicationMain (argc=1, argv=0x7fffffffd330) at Functions.m:83

So I set up a memory watch for anObject and then I get this:

Hardware watchpoint 4: *0x1843d58

Old value = -140067648
New value = -559023410
0x00007ffff5b81060 in object_setClass () from /usr/lib64/
(gdb) bt
#0  0x00007ffff5b81060 in object_setClass () from /usr/lib64/
#1  0x00007ffff6171b45 in NSDeallocateObject (anObject=0x1843d58) at NSObject.m:855
#2  0x00007ffff61723fc in -[NSObject dealloc] (self=0x1843d58, _cmd=0x7ffff7a00880 <.objc_selector_list+2464>) at NSObject.m:1385
#3  0x00007ffff745ffc1 in -[NSCell dealloc] (self=0x1843d58, _cmd=0x7ffff79fc290 <.objc_selector_list+1648>) at NSCell.m:234
#4  0x00007ffff7455537 in -[NSButtonCell dealloc] (self=0x1843d58, _cmd=0x7ffff7a53ec0 <.objc_selector_list+832>) at NSButtonCell.m:185
#5  0x00007ffff75390b0 in -[NSMenuItemCell dealloc] (self=0x1843d58, _cmd=0x7ffff7a6c490 <.objc_selector_list+1856>) at NSMenuItemCell.m:112
#6  0x00007ffff755cd05 in -[NSPopUpButtonCell dealloc] (self=0x1843d58, _cmd=0x7ffff6678370 <.objc_selector_list+560>) at NSPopUpButtonCell.m:158
#7  0x00007ffff6173739 in -[NSObject release] (self=0x1843d58, _cmd=0x7ffff6662ff0 <.objc_selector_list+784>) at NSObject.m:2070
#8  0x00007ffff61391b4 in GSIArraySetItemAtIndex (array=0x13b6770, item=..., index=66) at ../Headers/GNUstepBase/GSIArray.h:531
#9  0x00007ffff6139911 in -[NSKeyedUnarchiver(Private) _decodeObject:] (self=0xdf0dc8, _cmd=0x7ffff6662fe0 <.objc_selector_list+768>, index=66) at NSKeyedUnarchiver.m:273
#10 0x00007ffff613be6d in -[NSKeyedUnarchiver decodeObjectForKey:] (self=0xdf0dc8, _cmd=0x7ffff7a16aa0 <.objc_selector_list+80>, aKey=0x7ffff7a16940 <.objc_str151>)
    at NSKeyedUnarchiver.m:630
#11 0x00007ffff74a058e in -[NSControl initWithCoder:] (self=0x16a8d18, _cmd=0x7ffff660fdb0 <.objc_selector_list+144>, aDecoder=0xdf0dc8) at NSControl.m:1012
#12 0x000000010000680e in ?? ()
#13 0x00000000016a8d18 in ?? ()
#14 0x0000000000e42b90 in ?? ()
#15 0x00007fffffff4430 in ?? ()
#16 0x00007ffff76cc5e8 in -[NSClassSwapper instantiateRealObject:withClassName:] (self=0xe42b90, _cmd=0x16a8d18, coder=0x10000680e, className=0x7fffffff4390)
    at GSNibLoading.m:1416

Frames #12 - #15 are not relevant - basically it's just an -initWithCoder override in an NSPopUpButton subclass that just calls [super initWithCoder].

So the target object that was previously set to the NSMenuItem in question is now deallocated, so _target in NSMenuItem is now a dangling pointer.

To sum it up, it appears that the whole GUI structure of app's main window is first loaded when NSApplicationMain is called, but later on, [NSClassSwapper instantiateRealObject] causes some of the parts to be replaced, which leaves invalid pointers to previous instances behind.

I'm unable to fix it myself. I'd be grateful for any help.

Luboš Doležel

Gnustep-dev mailing list

reply via email to

[Prev in Thread] Current Thread [Next in Thread]