From a05d039055909d7d1dc2d4f31e1fe0659a3207dd Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 11 Jan 2017 11:45:41 -0500 Subject: [PATCH] Bug1567: intermittent failure to load libraries, plugins on Sierra... ... At startup, spawn a copy process in main() and crash it at once. The child process continues. (The fix was ineffective when the parent continued and the child crashed.) Re-activiation of the application is also needed or else the windows are hidden behind other applications. Another sleep when closing a project, to fix occurrences of the bug caused by closing of a project window without saving changes. --- mac/Audacity.xcodeproj/project.pbxproj | 2 +- src/AudacityApp.cpp | 36 +++++++++++++++++++++++--- src/AudacityApp.h | 11 ++++++++ src/MenusMac.cpp | 19 ++++++++++++++ src/Project.cpp | 9 +++++++ 5 files changed, 73 insertions(+), 4 deletions(-) diff --git a/mac/Audacity.xcodeproj/project.pbxproj b/mac/Audacity.xcodeproj/project.pbxproj index 06eac7a4d..5c674c792 100644 --- a/mac/Audacity.xcodeproj/project.pbxproj +++ b/mac/Audacity.xcodeproj/project.pbxproj @@ -2977,7 +2977,7 @@ 28FEC1B21A12B6FB00FACE48 /* EffectAutomationParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EffectAutomationParameters.h; path = ../include/audacity/EffectAutomationParameters.h; sourceTree = SOURCE_ROOT; }; 5E02BFF01D1164DF00EB7578 /* Distortion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Distortion.cpp; sourceTree = ""; }; 5E02BFF11D1164DF00EB7578 /* Distortion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Distortion.h; sourceTree = ""; }; - 5E0A0E301D23019A00CD2567 /* MenusMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MenusMac.cpp; sourceTree = ""; }; + 5E0A0E301D23019A00CD2567 /* MenusMac.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = MenusMac.cpp; sourceTree = ""; }; 5E4685F81CCA9D84008741F2 /* CommandFunctors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommandFunctors.h; sourceTree = ""; }; 5E61EE0C1CBAA6BB0009FCF1 /* MemoryX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryX.h; sourceTree = ""; }; 5E74D2D91CC4427B00D88B0B /* TrackPanelCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCell.h; sourceTree = ""; }; diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index d5bbc3fbf..aed427513 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -663,12 +663,36 @@ IMPLEMENT_WX_THEME_SUPPORT int main(int argc, char *argv[]) { - if (getenv("DYLD_LIBRARY_PATH")) { - extern char **environ; + bool doCrash = false; - unsetenv("DYLD_LIBRARY_PATH"); +#ifdef FIX_BUG1567 + doCrash = AudacityApp::IsSierraOrLater(); +#endif + + bool doExec = !doCrash && getenv("DYLD_LIBRARY_PATH"); + unsetenv("DYLD_LIBRARY_PATH"); + + extern char **environ; + +#ifdef FIX_BUG1567 + const char *var_name = "_NO_CRASH"; + if ( doCrash && !( getenv( var_name ) ) ) { + setenv(var_name, "1", TRUE); + // Bizarre fix for Bug1567 + // Crashing one Audacity and immediately starting another avoids intermittent + // failures to load libraries on Sierra + if ( fork() ) + // The original process crashes at once + raise(SIGTERM); + + // Child process can't proceed until doing this: execve(argv[0], argv, environ); } + else +#else + if (doExec) + execve(argv[0], argv, environ); +#endif wxDISABLE_DEBUG_SUPPORT(); @@ -1425,6 +1449,12 @@ bool AudacityApp::OnInit() temporarywindow.SetTitle(_("Audacity is starting up...")); SetTopWindow(&temporarywindow); +#ifdef FIX_BUG1567 + // Without this, splash screen may be hidden under other programs. + if (IsSierraOrLater()) + MacActivateApp(); +#endif + // ANSWER-ME: Why is YieldFor needed at all? //wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI|wxEVT_CATEGORY_USER_INPUT|wxEVT_CATEGORY_UNKNOWN); wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI); diff --git a/src/AudacityApp.h b/src/AudacityApp.h index 030fe7baa..ce2832ea3 100644 --- a/src/AudacityApp.h +++ b/src/AudacityApp.h @@ -286,6 +286,17 @@ class AudacityApp final : public wxApp { void GenerateCrashReport(wxDebugReport::Context ctx); #endif +#ifdef __WXMAC__ + + #if ! defined(__WXDEBUG__) + #define FIX_BUG1567 + #endif + + void MacActivateApp(); + static bool IsSierraOrLater(); + +#endif + private: std::unique_ptr mCmdHandler; std::unique_ptr mRecentFiles; diff --git a/src/MenusMac.cpp b/src/MenusMac.cpp index 33b717490..03ef74fe5 100644 --- a/src/MenusMac.cpp +++ b/src/MenusMac.cpp @@ -6,6 +6,9 @@ // // +// This file collects a few things specific to Mac and requiring some +// Objective-C++ . Avoid mixing languages elsewhere. + #include "Audacity.h" #include "Project.h" @@ -16,6 +19,9 @@ #include #endif +#include +#include + void AudacityProject::DoMacMinimize(AudacityProject *project) { auto window = project; @@ -78,3 +84,16 @@ void AudacityProject::OnMacBringAllToFront() project->Raise(); } } + +void AudacityApp::MacActivateApp() +{ + id app = [NSApplication sharedApplication]; + if ( [app respondsToSelector:@selector(activateIgnoringOtherApps:)] ) + [app activateIgnoringOtherApps:YES]; +} + +bool AudacityApp::IsSierraOrLater() +{ + auto number = kCFCoreFoundationVersionNumber; + return number >= 1348.1; +} diff --git a/src/Project.cpp b/src/Project.cpp index 53996877a..194eaef9c 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -2626,6 +2626,15 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event) // have been deleted before this. mDirManager.reset(); +#ifdef FIX_BUG1567 + // PRL: part of Bug1567: + // This sleep after destroying the block files may avoid problems on macOS + // Sierra and later, when quitting a project (but not the program) without + // saving the file. + if (AudacityApp::IsSierraOrLater()) + ::wxMilliSleep(1000); +#endif + AProjectHolder pSelf; { ODLocker locker{ &AudacityProject::AllProjectDeleteMutex() };