macOS: opt out of AppKit window restoration, catch SIGTRAP - #6974
Merged
Merged
Conversation
After MeshInspector.app was killed by SIGTRAP, every later launch on the MACBOOK-PRO-16-2021-TBI-2 runner hung inside glfwInit(): [NSApp run] waits for launch to finish, and AppKit's window restoration can block there after an abnormal exit. GLFW windows are never restorable, so register ApplePersistence = NO before launch. On arm64, __builtin_trap() raises SIGTRAP, which printStacktraceOnCrash did not handle, so those crashes left no stack trace in the log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fedr
approved these changes
Sep 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since 2026-09-29 13:35 UTC, MeshInspectorCode's "Run Start-and-Exit Test" hangs on every job that runs on the self-hosted runner
MACBOOK-PRO-16-2021-TBI-2(macOS 15, arm64), on PRs and master alike, until the step's 3-minute timeout. The same commits pass on the other macOS runners. The log stops insideglfwInit():Log file: ...is printed,glfwInit succeedednever is, and the process sits at 0% CPU. MeshViewer, which is not an app bundle, still gets throughglfwInit()on the same runner.The hangs started right after UI tests on two MeshInspectorCode branches killed
MeshInspector.appwith SIGTRAP (rc=-5), five times in each run, and both times the next launch hung. The crashes came from the macOS atexit bug that #6864 introduced and #6969 already fixed; this PR is about the hang they left behind.glfwInit()calls[NSApp run]to finish launching, and inside that call AppKit's window restoration (NSPersistentUIManager) can block. After an abnormal exit it may show a "reopen windows?" alert that nobody answers, or wait on the restoration service (talagentd). Each hung run is then killed by the timeout, which is another abnormal exit, so the runner likely stays stuck.MRMacOSOpenDocumentsHandler.mm: its+load, which already runs beforemain, now registersApplePersistence = NO, so AppKit skips window restoration at launch. GLFW creates every window withsetRestorable:NO, so nothing is lost.registerDefaults:only sets an in-memory fallback, the same way GLFW setsApplePressAndHoldEnabled. An Electron app (zero-abd/teamree, PR 170) fixed a launch hang in the same AppKit code with the same registration.MRStacktrace.cpp:printStacktraceOnCrashnow also handles SIGTRAP. On arm64,__builtin_trap()raises SIGTRAP (on x86-64 it is SIGILL, which is already handled), so those crashes skipped the handler. TBI-2's logs have no "Crash signal" line or stack trace for them, while the other runners logged theirs for the same bug. Debuggers get breakpoint traps before the process does, so debugging is unaffected.Side effects
std::exit(5), so the exit code is 5 instead of death by signal (rc=-5). MeshInspectorCode's UI tests only check for 0, so they fail the same way; only the printed code changes.std::exitruns static destructors and atexit handlers. In MeshInspector,~EmbeddedPythonthen finalizes the embedded interpreter, which runs Pythonatexitcallbacks such as the viewer shutdown from Python viewer: live at the macOS prompt through PyOS_InputHook, shut down on interpreter exit #6864. SIGSEGV, SIGABRT and SIGILL already take this path, and it can crash again inside the handler and hang: on 2026-09-29, MacBook-Pro-Daniil went 11 → 6 → 11 in the handler and then sat until the 500 s timeout.+loadruns in every process that loads MRViewer, including Python with meshlib's viewer, so restoration is off for the whole process, not only for GLFW windows. It is in-memory only, and a host that wants restoration back can register its ownApplePersistencevalue before launch. The same+loadalready setsNSTreatUnknownArgumentsAsOpenfor every host, and that one is saved to disk.Test plan
🤖 Generated with Claude Code