Subject: Re: bug#59794: 29.0.60; NSport segfaults when a fullscreen frame is being closed

From: Po Lu <[email-masked]>
Date: Sat, 03 Dec 2022 18:08:56 +0800

Kai Ma <[email-masked]> writes:

> Emacs segfaults when a fullscreen frame is being deleted.
>
> Steps to reproduce on emacs -Q:
>
> 1. Launch an emacs instance.  The default frame should be in the window
>    mode for now.
>
> 2. C-x 5 2
>
> 3. In the new frame, M-x toggle-frame-fullscreen.
>
> 4. In the new frame, C-x 5 0 to delete the frame.
>
> Emacs then segfaults.
>
> LLDB trace:
>
> * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xc0)
>     frame #0: 0x0000000100238ed5 emacs`-[EmacsView resetCursorRects](self=0x0000000102e3ddd0, _cmd=<unavailable>) at nsterm.m:6707:29 [opt]
>    6704	- (void)resetCursorRects
>    6705	{
>    6706	  NSRect visible = [self visibleRect];
> -> 6707	  NSCursor *currentCursor = FRAME_POINTER_TYPE (emacsframe);
>    6708	  NSTRACE ("[EmacsView resetCursorRects]");
>    6709
>    6710	  if (currentCursor == nil)
> Target 0: (emacs) stopped.
> warning: emacs was compiled with optimization - stepping may behave oddly; variables may not be available.
> (lldb) bt
> * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xc0)
>   * frame #0: 0x0000000100238ed5 emacs`-[EmacsView resetCursorRects](self=0x0000000102e3ddd0, _cmd=<unavailable>) at nsterm.m:6707:29 [opt]
>     frame #1: 0x00007ff819be1b95 AppKit`-[_NSTrackingAreaAKViewHelper updateTrackingAreasWithInvalidCursorRects:] + 357
>     frame #2: 0x00007ff819e520f0 AppKit`_NSViewSubViewMutationSafeApply + 227
>     frame #3: 0x00007ff819be1c53 AppKit`-[_NSTrackingAreaAKViewHelper updateTrackingAreasWithInvalidCursorRects:] + 547
>     frame #4: 0x00007ff819e520f0 AppKit`_NSViewSubViewMutationSafeApply + 227
>     frame #5: 0x00007ff819be1c53 AppKit`-[_NSTrackingAreaAKViewHelper updateTrackingAreasWithInvalidCursorRects:] + 547
>     frame #6: 0x00007ff819bdfddf AppKit`-[_NSTrackingAreaAKManager displayCycleUpdateStructuralRegions] + 227
>     frame #7: 0x00007ff8195f4a84 AppKit`__NSWindowGetDisplayCycleObserverForUpdateStructuralRegions_block_invoke + 390
>     frame #8: 0x00007ff8195ef701 AppKit`NSDisplayCycleObserverInvoke + 142
>     frame #9: 0x00007ff8195ef331 AppKit`NSDisplayCycleFlush + 878
>     frame #10: 0x00007ff81de68f46 QuartzCore`CA::Transaction::run_commit_handlers(CATransactionPhase) + 98
>     frame #11: 0x00007ff81de67a10 QuartzCore`CA::Transaction::commit() + 380
>     frame #12: 0x00007ff81968cedf AppKit`__62+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayLink]_block_invoke + 285
>     frame #13: 0x00007ff819ea3513 AppKit`___NSRunLoopObserverCreateWithHandler_block_invoke + 41
>     frame #14: 0x00007ff81640d0e2 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
>     frame #15: 0x00007ff81640d00a CoreFoundation`__CFRunLoopDoObservers + 482
>     frame #16: 0x00007ff81640c590 CoreFoundation`__CFRunLoopRun + 870
>     frame #17: 0x00007ff81640bbb0 CoreFoundation`CFRunLoopRunSpecific + 560
>     frame #18: 0x00007ff81fcedbd6 HIToolbox`RunCurrentEventLoopInMode + 292
>     frame #19: 0x00007ff81fced9e6 HIToolbox`ReceiveNextEventCommon + 679
>     frame #20: 0x00007ff81fced723 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 70
>     frame #21: 0x00007ff81952eb37 AppKit`_DPSNextEvent + 909
>     frame #22: 0x00007ff81952d9b8 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1219
>     frame #23: 0x00007ff81951fff3 AppKit`-[NSApplication run] + 586
>     frame #24: 0x000000010023680d emacs`-[EmacsApp run](self=0x0000000102e09540, _cmd=<unavailable>) at nsterm.m:5818:7 [opt]
>     frame #25: 0x0000000100235395 emacs`ns_select_1(nfds=0, readfds=0x00007ff7bfefdcb0, writefds=0x00007ff7bfefdc00, exceptfds=0x0000000000000000, timeout=0x00007ff7bfefddb0, sigmask=0x0000000000000000, run_loop_only=NO) at nsterm.m:4833:3 [opt]
>     frame #26: 0x0000000100234f54 emacs`ns_select(nfds=<unavailable>, readfds=<unavailable>, writefds=<unavailable>, exceptfds=<unavailable>, timeout=<unavailable>, sigmask=<unavailable>) at nsterm.m:4885:10 [opt]

This time I cannot reproduce the bug on GNUstep.

It looks as if a reference to the EmacsFrame is being kept even after
the frame has been destroyed.  Would someone who knows what
`NSView resetCursorRects' does in Mac OS speak up?