From 22306aa6b8f6ab3c113d5d6ec08fe73f4c79ceed 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 8e807c375143e..2a73c54e0cba0 100644 --- a/onnxruntime/core/session/provider_bridge_ort.cc +++ b/onnxruntime/core/session/provider_bridge_ort.cc @@ -1522,24 +1522,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() {