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

From: Kai Ma <[email-masked]>
Date: Sat, 03 Dec 2022 18:48:15 +0800

I did some investigation, but I was unable to identify the problem on
the Emacs side.

I traced the code, and found that even after [[view window] close] is
called (nsterm.m L1626), [EmacsView resetCursorRects:] can still be
invoked for that window.  To my understanding, such calls are initiated
by AppKit, not in the control of Emacs.

Also, Emacs 27 and Emacs 28 (NS) also suffer from exactly the same issue
(the same invalid access).  I was unable to reproduce it using the Mac
port.  Given the severity of segfaults, I suspect it's very likely due
to upstream Cocoa changes that only cause problems on newer versions of
macOS.

I'm currently using the trivial fix to prevent further data loss:

>From 8ea35a8099f34f482d090ea8068e89f52dcd29ac Mon Sep 17 00:00:00 2001
From: Kai Ma <[email-masked]>
Date: Sat, 3 Dec 2022 18:17:26 +0800
Subject: [PATCH] Prevent a segfault when deleting a fullscreen frame on
 NextStep.

* nsterm.m ([EmacsView resetCursorRects:]): Be defensive when
accessing FRAME_OUTPUT_DATA.
---
 src/nsterm.m | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index 507f2a9e7d..c09f743ec7 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6703,8 +6703,16 @@ - (BOOL)acceptsFirstResponder
 
 - (void)resetCursorRects
 {
-  NSRect visible = [self visibleRect];
-  NSCursor *currentCursor = FRAME_POINTER_TYPE (emacsframe);
+  NSRect visible;
+  NSCursor *currentCursor;
+
+  /* On macOS 13, [resetCursorRects:] could be called even after the
+     window is closed. */
+  if (! emacsframe || ! FRAME_OUTPUT_DATA (emacsframe))
+    return;
+
+  visible = [self visibleRect];
+  currentCursor = FRAME_POINTER_TYPE (emacsframe);
   NSTRACE ("[EmacsView resetCursorRects]");
 
   if (currentCursor == nil)
-- 
2.37.1 (Apple Git-137.1)