Closed svgol closed 5 months ago
The attached app contains two meaningful methods -[AppDelegate applicationDidFinishLaunching:] where the dynamic GUI is created 10 times and -[MainWindowController windowWillClose:] where the WindowController is autoreleased.
Uncomment the line MainWindowController.m:16
//[textView setDelegate: nil]; // libs-gui doesn't do it... BUG???
and no crash happens.
The crash has gone with the #gnustep/libs-base/issues/381 is fixed.
Closing, as it was fixed in base. I will still add one line to gui setting the delegate to nil, just to make sure.
I have an app that downloads a media file and creates a window to show progress of downloading in an NSTextView (the output of the tool ytdl used to download the file). It creates the window with -[initWithWindowNibName:] of a NSWindowController's descendant. When downloading is done the descendant receives -[close] and then it is autoreleased in its -[windowWillClose:]. The descendant is a delegate of the NSTextView. Sometimes it crashes with the following stacktrace:
0 0x00007ffff7f9b875 in objc_msg_lookup (receiver=0x555556026c30, op=0x7ffff7479a30 <_OBJC_SELECTOR_TABLE+80>) at /usr/src/debug/gcc/gcc/libobjc/sendmsg.c:442
1 0x00007ffff711305e in -[NSNotificationCenter removeObserver:name:object:] (self=0x555555778480, _cmd=0x7ffff7dc22a0 <_OBJC_SELECTOR_TABLE+608>,
2 0x00007ffff7a7e661 in -[NSTextView dealloc] (self=0x5555558fc6e0, _cmd=0x7ffff7484670 <_OBJC_SELECTOR_TABLE+48>) at NSTextView.m:1144
3 0x00007ffff71222e7 in objc_release_fast_np_internal (anObject=0x5555558fc6e0) at NSObject.m:568
4 0x00007ffff7122306 in release_fast (anObject=0x5555558fc6e0) at NSObject.m:582
5 0x00007ffff712426f in -[NSObject release] (self=0x5555558fc6e0, _cmd=0x7ffff74a77d0 <_OBJC_SELECTOR_TABLE+80>) at NSObject.m:2079
6 0x00007ffff7174736 in -[GSRunLoopPerformer dealloc] (self=0x555555bb44c0, _cmd=0x7ffff7484670 <_OBJC_SELECTOR_TABLE+48>) at NSRunLoop.m:113
7 0x00007ffff71222e7 in objc_release_fast_np_internal (anObject=0x555555bb44c0) at NSObject.m:568
8 0x00007ffff7122306 in release_fast (anObject=0x555555bb44c0) at NSObject.m:582
9 0x00007ffff712426f in -[NSObject release] (self=0x555555bb44c0, _cmd=0x7ffff74a77d0 <_OBJC_SELECTOR_TABLE+80>) at NSObject.m:2079
10 0x00007ffff7175bf7 in -[NSRunLoop(Private) _checkPerformers:] (self=0x5555557cc020, _cmd=0x7ffff74a7bd0 <_OBJC_SELECTOR_TABLE+1104>, context=0x5555557aed60)
11 0x00007ffff7177874 in -[NSRunLoop acceptInputForMode:beforeDate:] (self=0x5555557cc020, _cmd=0x7ffff74a7c50 <_OBJC_SELECTOR_TABLE+1232>,
12 0x00007ffff717819c in -[NSRunLoop runMode:beforeDate:] (self=0x5555557cc020, _cmd=0x7ffff7df4b20 <_OBJC_SELECTOR_TABLE+768>,
13 0x00007ffff7af3777 in -[GSDisplayServer(EventOps) getEventMatchingMask:beforeDate:inMode:dequeue:] (self=0x5555557f4060,
14 0x00007ffff2ddca21 in -[XGServer(X11Ops) getEventMatchingMask:beforeDate:inMode:dequeue:] (self=0x5555557f4060, _cmd=0x7ffff7c8e4b0 <_OBJC_SELECTOR_TABLE+1648>,
15 0x00007ffff787e86d in DPSGetEvent (ctxt=0x5555557f4060, mask=4294967295, limit=0x555555815f90, mode=0x7ffff74a6a00 <_OBJC_INSTANCE_2>)
16 0x00007ffff7885cc6 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] (self=0x55555586fa00, _cmd=0x7ffff7c8e9b0 <_OBJC_SELECTOR_TABLE+2928>,
17 0x00007ffff7884002 in -[NSApplication run] (self=0x55555586fa00, _cmd=0x7ffff7c79150 <_OBJC_SELECTOR_TABLE+1904>) at NSApplication.m:1582
18 0x00007ffff785bc1a in NSApplicationMain (argc=1, argv=0x7fffffffe198) at Functions.m:119
19 0x00005555555589b5 in main (argc=1, argv=0x7fffffffe198) at CrashAfterWinControllerDeallocation_main.m:28
The cause is that conditions exist allowing NSTextView is deallocated AFTER its delegate. NSTextView registers itself in NSRunLoop as a performer to receive periodic updates. This can lead to -[NSTextView dealloc] is called when the delegate has gone and the following chunk:
causes crashes. Adding the following snippet to -[NSWindowController dealloc] can guard from crashes (provided lib-base fixes a related issue around NSNotificationCenter.m:1050):
Also I believe that changing a state of another objects must not belong to any -dealloc (except for very rare and well documented cases) so the above mentioned chunk in -[NSTextView dealloc] should be removed.