From 18ac4c22887710f24b3ce092001a2fdafa191241 Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Wed, 19 Apr 2023 20:38:12 -0400 Subject: [PATCH] Handle OnKifaceStart exceptions without crashing --- common/kiway.cpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/common/kiway.cpp b/common/kiway.cpp index 84670d3542..54774a2de6 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -287,15 +287,38 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad ) wxASSERT_MSG( kiface, wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) ); + wxDllType dsoHandle = dso.Detach(); + + bool startSuccess = false; + // Give the DSO a single chance to do its "process level" initialization. // "Process level" specifically means stay away from any projects in there. - if( kiface->OnKifaceStart( m_program, m_ctl ) ) - { - // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. - ignore_unused( dso.Detach() ); + try + { + startSuccess = kiface->OnKifaceStart( m_program, m_ctl ); + } + catch (...) + { + // OnKiFaceStart may generate an exception + // Before we continue and ultimately unload our module to retry we need + // to process the exception before we delete the free the memory space the exception resides in + Pgm().HandleException( std::current_exception() ); + } + + if( startSuccess ) + { return m_kiface[aFaceId] = kiface; } + else + { + // Usually means cancelled initial global library setup + // But it could have been an exception/failure + // Let the module go out of scope to unload + dso.Attach( dsoHandle ); + + return nullptr; + } } // In any of the failure cases above, dso.Unload() should be called here