From 2b02747ec56d601124a37c3992d4bd1fe3ef4881 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Thu, 7 Jan 2021 19:14:48 +0100 Subject: [PATCH] On OSX, we use boost::process::spawn() to launch new instances of PrusaSlicer from another PrusaSlicer. boost::process::spawn() sets SIGCHLD to SIGIGN for the child process, thus if a child PrusaSlicer spawns another subprocess and the subrocess dies, the child PrusaSlicer will not receive information on end of subprocess (posix waitpid() call will always fail). https://jmmv.dev/2008/10/boostprocess-and-sigchld.html The child instance of PrusaSlicer has to reset SIGCHLD to its default, so that posix waitpid() and similar continue to work. Fixes #5507 --- src/slic3r/GUI/GUI_Init.cpp | 15 +++++++++++++++ src/slic3r/Utils/Process.cpp | 12 ++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GUI_Init.cpp b/src/slic3r/GUI/GUI_Init.cpp index 70536c6ba..839782741 100644 --- a/src/slic3r/GUI/GUI_Init.cpp +++ b/src/slic3r/GUI/GUI_Init.cpp @@ -16,11 +16,26 @@ #include #include +#if __APPLE__ + #include +#endif // __APPLE__ + namespace Slic3r { namespace GUI { int GUI_Run(GUI_InitParams ¶ms) { +#if __APPLE__ + // On OSX, we use boost::process::spawn() to launch new instances of PrusaSlicer from another PrusaSlicer. + // boost::process::spawn() sets SIGCHLD to SIGIGN for the child process, thus if a child PrusaSlicer spawns another + // subprocess and the subrocess dies, the child PrusaSlicer will not receive information on end of subprocess + // (posix waitpid() call will always fail). + // https://jmmv.dev/2008/10/boostprocess-and-sigchld.html + // The child instance of PrusaSlicer has to reset SIGCHLD to its default, so that posix waitpid() and similar continue to work. + // See GH issue #5507 + signal(SIGCHLD, SIG_DFL); +#endif // __APPLE__ + try { GUI::GUI_App* gui = new GUI::GUI_App(params.start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor); if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) { diff --git a/src/slic3r/Utils/Process.cpp b/src/slic3r/Utils/Process.cpp index 1199e5e76..a8fc59f52 100644 --- a/src/slic3r/Utils/Process.cpp +++ b/src/slic3r/Utils/Process.cpp @@ -17,7 +17,6 @@ // For starting another PrusaSlicer instance on OSX. // Fails to compile on Windows on the build server. #ifdef __APPLE__ - #include #include #include #endif @@ -79,11 +78,12 @@ static void start_new_slicer_or_gcodeviewer(const NewSlicerInstanceType instance if (instance_type == NewSlicerInstanceType::Slicer && single_instance) args.emplace_back("--single-instance"); boost::process::spawn(bin_path, args); - // boost::process::spawn() sets SIGINT to SIGIGN, which collides with boost::process waiting for a child to finish! - // https://jmmv.dev/2008/10/boostprocess-and-sigchld.html - // Thus reset the SIGINT to its default, so that posix waitpid() and similar continue to work. - // Fixes Crash on Eject in Second Instance on macOS #5507 - signal(SIGINT, SIG_DFL); + // boost::process::spawn() sets SIGCHLD to SIGIGN for the child process, thus if a child PrusaSlicer spawns another + // subprocess and the subrocess dies, the child PrusaSlicer will not receive information on end of subprocess + // (posix waitpid() call will always fail). + // https://jmmv.dev/2008/10/boostprocess-and-sigchld.html + // The child instance of PrusaSlicer has to reset SIGCHLD to its default, so that posix waitpid() and similar continue to work. + // See GH issue #5507 } catch (const std::exception& ex) { BOOST_LOG_TRIVIAL(error) << "Failed to spawn a new slicer \"" << bin_path.string() << "\": " << ex.what();