Bug 6156 - [gtk] Quitting the application with unsaved file and answering Cancel results in crash
Summary: [gtk] Quitting the application with unsaved file and answering Cancel results...
Status: RESOLVED FIXED
Alias: None
Product: Xamarin Studio
Classification: Desktop
Component: General ()
Version: 3.0.x
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-07-17 10:40 UTC by Attila Tamás Zimler
Modified: 2015-08-21 06:07 UTC (History)
5 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Crash log of the application. (63.43 KB, text/plain)
2012-07-17 10:40 UTC, Attila Tamás Zimler
Details
Patch that fixes the crash (729 bytes, patch)
2012-07-17 17:40 UTC, Mikayla Hutchinson [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Attila Tamás Zimler 2012-07-17 10:40:20 UTC
Created attachment 2211 [details]
Crash log of the application.

Quitting the application from the MacOSX Dock bar and answering Cancel to an unsaved file results in crash.

See screencast of the bug at: http://screencast.com/t/dsUxKv0H1N
Comment 1 Mikayla Hutchinson [MSFT] 2012-07-17 16:56:07 UTC
This looks to me like a GTK issue - it looks like the NSDate that GTK is passing to [NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] is getting released.

Here is an annotated lldb log demonstrating my reasoning. I used lldb because gdb gave incorrect values, and I didn't believe it :)

//attach to process

(lldb) process attach -n mono
Process 42235 stopped
Executable module set to "/Library/Frameworks/Mono.framework/Versions/Current/bin/mono".
Architecture set to: i386.

//breakpoint on abort

(lldb) b abort
breakpoint set --name 'abort'
Breakpoint created: 1: name = 'abort', locations = 1, resolved = 1

//resume execution

(lldb) continue
Process 42235 resuming

//repro the bug

Process 42235 stopped
* thread #1: tid = 0x2003, 0x92531e87 libobjc.A.dylib`objc_msgSend_fpret + 23, stop reason = EXC_BAD_ACCESS (code=1, address=0xd093d4d3)
    frame #0: 0x92531e87 libobjc.A.dylib`objc_msgSend_fpret + 23
libobjc.A.dylib`objc_msgSend_fpret + 23:
-> 0x92531e87:  movl   32(%edx), %edi
   0x92531e8a:  pushl  %esi
   0x92531e8b:  movl   (%edi), %esi
   0x92531e8d:  movl   %ecx, %edx

//get the receiver 
// see http://sealiesoftware.com/blog/archive/2008/09/22/objc_explain_So_you_crashed_in_objc_msgSend.html

(lldb) p/x $eax
(unsigned int) $0 = 0x0fc6f150

//backtrace

(lldb) bt
* thread #1: tid = 0x2003, 0x92531e87 libobjc.A.dylib`objc_msgSend_fpret + 23, stop reason = EXC_BAD_ACCESS (code=1, address=0xd093d4d3)
    frame #0: 0x92531e87 libobjc.A.dylib`objc_msgSend_fpret + 23
    frame #1: 0x917238fd AppKit`_DPSNextEvent + 2763
    frame #2: 0x91722942 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 113
    frame #3: 0x0470de97 libgdk-quartz-2.0.0.dylib`poll_func + 289
    frame #4: 0x040bbff5 libglib-2.0.0.dylib`g_main_context_poll + 268
    frame #5: 0x040bb3a9 libglib-2.0.0.dylib`g_main_context_iterate + 1141
    frame #6: 0x040bbbb6 libglib-2.0.0.dylib`g_main_loop_run + 932
    frame #7: 0x042edaa7 libgtk-quartz-2.0.0.dylib`gtk_main + 239
    frame #8: 0x0e0f3554
    frame #9: 0x0e0f351c
    frame #10: 0x0e0f34fc
    frame #11: 0x028cb5cc
    frame #12: 0x006a2f90
    frame #13: 0x006a2d9c
    frame #14: 0x006a2e56
    frame #15: 0x0000ecf4 mono`mono_jit_runtime_invoke + 164 at mini.c:5791
    frame #16: 0x00184354 mono`mono_runtime_invoke + 68 at object.c:2755
    frame #17: 0x0018a4a1 mono`mono_runtime_exec_main + 369 at object.c:3930
    frame #18: 0x0007464d mono`mono_main + 6797 at driver.c:1003

//examine the NSDate passed to nextEventMatchingMask:untilDate:inMode:dequeue: by GTK's poll_func
// see http://www.clarkcox.com/blog/2009/02/04/inspecting-obj-c-parameters-in-gdb/

(lldb) frame select 2
frame #2: 0x91722942 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 113
AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 113:
-> 0x91722942:  subl   $4, %esp
   0x91722945:  movl   -208(%ebp), %eax
   0x9172294b:  testl  %eax, %eax
   0x9172294d:  jne    0x91722956               ; -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 133
(lldb) p/x *(int*)($ebp+20)
(int) $1 = 0x0fc6f150

This parameter value matches the receiver of the objc_msgSend_fpret call that aborted. Therefore, it is likely that this object has been released.

To confirm this was possible, I ran the app again and obtained a backtrace from the app while it was displaying the "would you like to save" dialog.

* thread #1: tid = 0x2003, 0x9ad2b9fa libsystem_c.dylib`OSAtomicCompareAndSwap64$VARIANT$mp + 26, stop reason = signal SIGSTOP
    frame #0: 0x9ad2b9fa libsystem_c.dylib`OSAtomicCompareAndSwap64$VARIANT$mp + 26
    frame #1: 0x9ace1651 libsystem_c.dylib`pthread_mutex_lock + 539
    frame #2: 0x958af0ee CoreFoundation`CFRunLoopRunSpecific + 94
    frame #3: 0x958af088 CoreFoundation`CFRunLoopRunInMode + 120
    frame #4: 0x94a90723 HIToolbox`RunCurrentEventLoopInMode + 318
    frame #5: 0x94a979b6 HIToolbox`ReceiveNextEventCommon + 168
    frame #6: 0x94a978fa HIToolbox`BlockUntilNextEventMatchingListInMode + 88
    frame #7: 0x917230d8 AppKit`_DPSNextEvent + 678
    frame #8: 0x91722942 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 113
    frame #9: 0x05101e97 libgdk-quartz-2.0.0.dylib`poll_func + 289
    frame #10: 0x04ac0ff5 libglib-2.0.0.dylib`g_main_context_poll + 268
    frame #11: 0x04ac03a9 libglib-2.0.0.dylib`g_main_context_iterate + 1141
    frame #12: 0x04ac0bb6 libglib-2.0.0.dylib`g_main_loop_run + 932
    frame #13: 0x04c42a51 libgtk-quartz-2.0.0.dylib`gtk_dialog_run + 542
    frame #14: 0x0fd8ff7c
    frame #15: 0x0fdb1ff8
    frame #16: 0x0fdb1ee8
    frame #17: 0x0fdb1be0
    frame #18: 0x0fdb1b18
    frame #19: 0x0fdad104
    frame #20: 0x0fdacfc8
    frame #21: 0x0fdacf78
    frame #22: 0x0fdace7c
    frame #23: 0x0fdacdce
    frame #24: 0x091c47cc
    frame #25: 0x94c1adec HIToolbox`_InvokeEventHandlerUPP(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*, long (*)(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*)) + 36
    frame #26: 0x94a964f3 HIToolbox`_ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1602
    frame #27: 0x94a95970 HIToolbox`_ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 482
    frame #28: 0x94a95788 HIToolbox`SendEventToEventTargetWithOptions + 75
    frame #29: 0x94aab3aa HIToolbox`_ZL29ToolboxEventDispatcherHandlerP25OpaqueEventHandlerCallRefP14OpaqueEventRefPv + 3152
    frame #30: 0x94a969ae HIToolbox`_ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 2813
    frame #31: 0x94a95970 HIToolbox`_ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 482
    frame #32: 0x94aaa755 HIToolbox`SendEventToEventTarget + 76
    frame #33: 0x94c2312e HIToolbox`_ZL20AEPredispatchHandlerPK6AEDescPS_l + 444
    frame #34: 0x9604e045 AE`aeDispatchAppleEvent(AEDesc const*, AEDesc*, unsigned long, unsigned char*) + 202
    frame #35: 0x96037b67 AE`_ZL25dispatchEventAndSendReplyPK6AEDescPS_ + 43
    frame #36: 0x96037a54 AE`aeProcessAppleEvent + 253
    frame #37: 0x94a9fc66 HIToolbox`AEProcessAppleEvent + 103
    frame #38: 0x91723347 AppKit`_DPSNextEvent + 1301
    frame #39: 0x91722942 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 113
    frame #40: 0x05101e97 libgdk-quartz-2.0.0.dylib`poll_func + 289
    frame #41: 0x04ac0ff5 libglib-2.0.0.dylib`g_main_context_poll + 268
    frame #42: 0x04ac03a9 libglib-2.0.0.dylib`g_main_context_iterate + 1141
    frame #43: 0x04ac0bb6 libglib-2.0.0.dylib`g_main_loop_run + 932
    frame #44: 0x04ce1aa7 libgtk-quartz-2.0.0.dylib`gtk_main + 239
    frame #45: 0x0e655aec
    frame #46: 0x0e655ab4
    frame #47: 0x0e655a94
    frame #48: 0x028be5cc
    frame #49: 0x00554f90
    frame #50: 0x00554d9c
    frame #51: 0x00554e56
    frame #52: 0x0000ecf4 mono`mono_jit_runtime_invoke + 164 at mini.c:5791
    frame #53: 0x00184354 mono`mono_runtime_invoke + 68 at object.c:2755
    frame #54: 0x0018a4a1 mono`mono_runtime_exec_main + 369 at object.c:3930
    frame #55: 0x0007464d mono`mono_main + 6797 at driver.c:1003

This trace confirmed that MonoDevelop's AppleEvent handler is dispatched within the nextEventMatchingMask:untilDate:inMode:dequeue: call. It's likely that in the callback, the current autorelease pool is drained by GTK. I suppose the fix for this is either to push/pop another autorelease pool for modal subloops, or to retain the NSDate before passing it to NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:.
Comment 2 Mikayla Hutchinson [MSFT] 2012-07-17 17:40:32 UTC
Created attachment 2214 [details]
Patch that fixes the crash

I've attached a patch that fixes the crash. Mitch, could you review and upstream?
Comment 3 Mikayla Hutchinson [MSFT] 2012-07-17 17:56:05 UTC
Landed patch in bockbuild.
Comment 4 Kristian Rietveld (inactive) 2012-07-18 04:35:32 UTC
Great debugging work!   Remembers me to still try lldb at some point.

I agree with the patch.

This is in poll_func I believe -- What we can also try is to initialize an autorelease 
pool at the beginning of poll_func and draining it at the end. This comes from http://bugzilla-attachments.gnome.org/attachment.cgi?id=212050 the remainder which of I don't agree with.
Comment 5 Mikayla Hutchinson [MSFT] 2012-07-18 12:51:37 UTC
Yeah, I considered that but thought it was overkill for a single object.
Comment 6 Kristian Rietveld (inactive) 2012-07-20 15:58:57 UTC
True -- I tend to agree here.  If Mitch agrees we should upstream this.
Comment 7 Kristian Rietveld (inactive) 2012-12-15 05:45:51 UTC
Mitch, this patch has not been upstreamed yet.  Do you think this is okay to be upstreamed? (Considering the changes to the polling code since the Summer).
Comment 8 Michael Natterer 2012-12-16 13:12:20 UTC
If this really still happens and the patch fixes it, please go ahead,
it is certainly safe to do.
Comment 9 Kristian Rietveld (inactive) 2013-07-08 06:22:38 UTC
Note that event loop handling is being fixed in upstream bug 701571. Issues are being addressed with respect to the recursive invocation of poll_func(). This is also present in the trace in comment 1 of this bug.

With the upstream patches applied, there should be no need for the patch in comment 2. This is because the new upstream patches will only refresh the autorelease pool when the main loop is not recursing through poll_func(), contrary to what we were seeing in comment 1 of this bug.
Comment 10 Kristian Rietveld (inactive) 2013-07-14 14:56:35 UTC
I have verified that this issue does not occur with the new upstream patches and the patch comment 2 removed.
Comment 11 Mikayla Hutchinson [MSFT] 2013-07-15 16:36:08 UTC
Updated the bockbuild patchset locally. Will push after some local testing.
Comment 12 Andres G. Aragoneses 2015-06-24 10:11:17 UTC
Hey guys, excuse me for jumping in.

> I have verified that this issue does not occur with the new upstream patches
> and the patch comment 2 removed.

Kristian, bgo#701571 is still not marked as FIXED. Does this mean that those patches have not yet been committed? Or that there's still work left to do in that bug?

If they indeed have been committed, do you mind pointing me to the first glib version that includes them? Thanks.


> Updated the bockbuild patchset locally. Will push after some local testing.

Hey Michael, seems you forgot to push this? I still see a patch for this bug in bockbuild master.
Comment 13 Andres G. Aragoneses 2015-06-24 10:18:10 UTC
Now that I look at the patches more closely, seems that I'm looking at the wrong place?

This glib patch points to this bug number:
https://github.com/mono/bockbuild/blob/master/packages/glib.py#L28

But that patch is for glib, while all the patches here and in the upstream bug seem to be for gtk+.

So I'm confused.
Comment 14 Lluis Sanchez 2015-08-21 06:07:04 UTC
Closing.