forked from viewit/OrcaSlicer-KX
fix(macos): prevent Bambu network plugin SIGABRT on app quit
libbambu_networking aborts inside its C++ static destructors during the exit() teardown on macOS while its background threads are still alive. Two quit paths reach that exit(): - App menu / Dock / logout: -[NSApplication terminate:] -> exit() bypasses wx OnExit()/~GUI_App. Override OSXOnWillTerminate() (the last wx hook before that exit()) to hard-exit via std::_Exit(0). - Cmd+Q / File>Quit / red button: graceful close -> ~GUI_App(). A guarded std::_Exit(0) at the end of ~GUI_App(), after all cleanup, covers it. macOS-only (#ifdef __APPLE__); Windows/Linux unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -2215,6 +2215,16 @@ GUI_App::~GUI_App()
|
||||
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": exit");
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Belt-and-suspenders for the graceful quit path (Cmd+Q / File>Quit / red button),
|
||||
// which reaches ~GUI_App() instead of OSXOnWillTerminate(). All app cleanup has run
|
||||
// by this point (config saved, network agent deleted, Bambu plugin shut down), so we
|
||||
// hard-exit to ensure the C runtime's exit() never runs libbambu_networking's static
|
||||
// destructors — they abort during teardown on macOS. This mirrors the app-menu/Dock/
|
||||
// logout path handled in GUI_App::OSXOnWillTerminate().
|
||||
std::_Exit(0);
|
||||
#endif /* __APPLE__ */
|
||||
}
|
||||
|
||||
bool GUI_App::is_blocking_printing(MachineObject *obj_)
|
||||
@ -2593,6 +2603,30 @@ int GUI_App::OnExit()
|
||||
return wxApp::OnExit();
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
// On macOS, quitting via the app menu / Dock / logout (or a system Quit AppleEvent)
|
||||
// routes through Cocoa's -[NSApplication terminate:], which calls exit() directly
|
||||
// from inside the native run loop. That bypasses wx's normal shutdown
|
||||
// (OnExit()/~GUI_App never run) and, during __cxa_finalize_ranges, runs the C++
|
||||
// static/atexit destructors of the closed-source Bambu networking plugin
|
||||
// (libbambu_networking) while its background threads are still alive. One of those
|
||||
// destructors calls std::terminate() -> abort(), producing a SIGABRT crash report
|
||||
// *after* the user has already quit (purely a teardown crash, no data at risk).
|
||||
//
|
||||
// OSXOnWillTerminate() is the last wx hook invoked before that exit(), and only
|
||||
// runs once termination has already been approved (OSXOnShouldTerminate() returned
|
||||
// no veto). We let the base class fire wxEVT_END_SESSION for any listeners, then
|
||||
// hard-exit with _Exit() so __cxa_finalize_ranges — and thus the plugin's crashing
|
||||
// destructors — never run. Nothing is persisted on this path today either, so this
|
||||
// is behavior-preserving apart from removing the cosmetic crash.
|
||||
void GUI_App::OSXOnWillTerminate()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "GUI_App::OSXOnWillTerminate: hard-exit to avoid Bambu network plugin teardown crash";
|
||||
wxApp::OSXOnWillTerminate();
|
||||
std::_Exit(0);
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
class wxBoostLog : public wxLog
|
||||
{
|
||||
void DoLogText(const wxString &msg) override {
|
||||
|
||||
@ -626,6 +626,10 @@ public:
|
||||
// wxWidgets override to get an event on open files.
|
||||
void MacOpenFiles(const wxArrayString &fileNames) override;
|
||||
void MacOpenURL(const wxString& url) override;
|
||||
// Last wx hook before Cocoa's exit() on the app-menu/Dock/logout quit path.
|
||||
// Hard-exits to skip the crashing static-destructor teardown of the Bambu
|
||||
// networking plugin. See implementation in GUI_App.cpp.
|
||||
void OSXOnWillTerminate() override;
|
||||
#endif /* __APPLE */
|
||||
|
||||
Sidebar& sidebar();
|
||||
|
||||
Reference in New Issue
Block a user