From eedf5a72547aa9af3abfe2c9623dac123b3dea21 Mon Sep 17 00:00:00 2001 From: adrianlizarraga Date: Thu, 24 Apr 2025 15:35:50 -0700 Subject: [PATCH] Fix segfault when re-loading an EP library --- .../core/session/provider_bridge_ort.cc | 1 + .../test/providers/qnn/qnn_basic_test.cc | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/onnxruntime/core/session/provider_bridge_ort.cc b/onnxruntime/core/session/provider_bridge_ort.cc index de56877ffe75a..f0fcf9841c2c1 100644 --- a/onnxruntime/core/session/provider_bridge_ort.cc +++ b/onnxruntime/core/session/provider_bridge_ort.cc @@ -1794,6 +1794,7 @@ void ProviderLibrary::Unload() { } } + initialized_ = false; handle_ = nullptr; provider_ = nullptr; } diff --git a/onnxruntime/test/providers/qnn/qnn_basic_test.cc b/onnxruntime/test/providers/qnn/qnn_basic_test.cc index b75751f89a6c7..f736abcd3006d 100644 --- a/onnxruntime/test/providers/qnn/qnn_basic_test.cc +++ b/onnxruntime/test/providers/qnn/qnn_basic_test.cc @@ -27,6 +27,8 @@ using namespace onnxruntime::logging; // in test_main.cc extern std::unique_ptr ort_env; +extern "C" void ortenv_setup(); +extern "C" void ortenv_teardown(); namespace onnxruntime { namespace test { @@ -1232,6 +1234,37 @@ TEST_F(QnnHTPBackendTests, UseHtpSharedMemoryAllocatorForInputs) { } #endif // BUILD_QNN_EP_STATIC_LIB +#if !BUILD_QNN_EP_STATIC_LIB +// Tests that loading and unloading of an EP library in the same process does not cause a segfault. +TEST_F(QnnHTPBackendTests, LoadingAndUnloadingOfQnnLibrary_FixSegFault) { + const ORTCHAR_T* ort_model_path = ORT_MODEL_FOLDER "nhwc_resize_sizes_opset18.quant.onnx"; + + onnxruntime::ProviderOptions options; + options["backend_type"] = "htp"; + options["offload_graph_io_quantization"] = "0"; + + // This first session will load the QNN EP library for the first time. + { + Ort::SessionOptions so; + so.AppendExecutionProvider("QNN", options); + + EXPECT_NO_THROW(Ort::Session session(*ort_env, ort_model_path, so)); + } + + { + ortenv_teardown(); // Destroy Env to force unloading of EP libraries. + ortenv_setup(); + + // This next session will reload the QNN EP library. + // Should not get a segfault. + Ort::SessionOptions so; + so.AppendExecutionProvider("QNN", options); + + EXPECT_NO_THROW(Ort::Session session(*ort_env, ort_model_path, so)); + } +} +#endif // !BUILD_QNN_EP_STATIC_LIB + #endif // defined(__aarch64__) || defined(_M_ARM64) || defined(__linux__) #endif // !defined(ORT_MINIMAL_BUILD)