From 2c9bdf9dea625fa9ed374e52a8f6fb806e13c065 Mon Sep 17 00:00:00 2001 From: zhenzew Date: Wed, 9 Oct 2024 02:43:53 -0700 Subject: [PATCH] [SharedLibrary] Fix the problem that throw cannot be executed normally after unload --- .../core/session/provider_bridge_ort.cc | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/onnxruntime/core/session/provider_bridge_ort.cc b/onnxruntime/core/session/provider_bridge_ort.cc index 85079ef78c8d3..cf78933a9af2f 100644 --- a/onnxruntime/core/session/provider_bridge_ort.cc +++ b/onnxruntime/core/session/provider_bridge_ort.cc @@ -1524,24 +1524,33 @@ struct ProviderLibrary { Provider& Get() { std::lock_guard lock{mutex_}; - try { - if (!provider_) { - s_library_shared.Ensure(); - - auto full_path = Env::Default().GetRuntimePath() + filename_; - ORT_THROW_IF_ERROR(Env::Default().LoadDynamicLibrary(full_path, false, &handle_)); - - Provider* (*PGetProvider)(); - ORT_THROW_IF_ERROR(Env::Default().GetSymbolFromLibrary(handle_, "GetProvider", (void**)&PGetProvider)); - - provider_ = PGetProvider(); - provider_->Initialize(); + if (!provider_) { + auto is_exception = 0; + std::runtime_error new_e("unknown"); // for rethrow + { + try { + s_library_shared.Ensure(); + + auto full_path = Env::Default().GetRuntimePath() + filename_; + ORT_THROW_IF_ERROR(Env::Default().LoadDynamicLibrary(full_path, false, &handle_)); + + Provider* (*PGetProvider)(); + ORT_THROW_IF_ERROR(Env::Default().GetSymbolFromLibrary(handle_, "GetProvider", (void**)&PGetProvider)); + + provider_ = PGetProvider(); + provider_->Initialize(); + } catch (const std::exception& e) { + // e is constructed in handle_'s dll and needs to be destroyed before unload + new_e = std::runtime_error(e.what()); + is_exception = 1; + } + } + if (is_exception) { + Unload(); // If anything fails we unload the library and rethrow + throw new_e; } - return *provider_; - } catch (const std::exception&) { - Unload(); // If anything fails we unload the library and rethrow - throw; } + return *provider_; } void Unload() {