From 24ff46e3cd41003f4f3557c9cbf4d887c8466829 Mon Sep 17 00:00:00 2001 From: Carlos Guzman Date: Fri, 27 Feb 2026 17:13:50 -0600 Subject: [PATCH] fix: prevent ShutdownAPI crashes when unloaded from Python/HDF5 VOL Disable SDK-managed curl and OpenSSL init/cleanup to avoid SIGSEGV in CleanupHttp() and CleanupCrypto() at process exit. When loaded as an HDF5 VOL plugin inside Python, the host process owns the curl/OpenSSL lifecycle and has already torn it down before the VOL terminate callback fires. Also switch SDKOptions to a global to ensure InitAPI/ShutdownAPI use the same options object. --- justfile | 11 +---------- lib/include/arraymorph/s3vl/initialize.h | 15 +++++++++------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/justfile b/justfile index 7a09ea9..a79b73f 100644 --- a/justfile +++ b/justfile @@ -30,17 +30,8 @@ dev: # Full build from scratch: deps → wheel build: wheel -# Test the built wheel in an isolated venv -test: - rm -rf .test-venv - uv venv .test-venv - source .test-venv/bin/activate.fish - uv pip install dist/arraymorph-0.2.0-*.whl - python3 -c "import arraymorph; print('Plugin:', arraymorph.get_plugin_path()); arraymorph.enable(); print('VOL enabled')" - rm -rf .test-venv - # Full build + test -all: build test +all: build # Clean build artifacts clean: diff --git a/lib/include/arraymorph/s3vl/initialize.h b/lib/include/arraymorph/s3vl/initialize.h index 2179cd3..2388528 100644 --- a/lib/include/arraymorph/s3vl/initialize.h +++ b/lib/include/arraymorph/s3vl/initialize.h @@ -28,13 +28,16 @@ inline herr_t S3VLINITIALIZE::s3VL_initialize_init(hid_t vipl_id) { // Aws::SDKOptions options; // Changed to use global sdk options for proper // shutdown g_sdk_options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Off; - // curl_global_init/cleanup is not re-entrant and must be called exactly once - // per process. Python (or another loaded library) may already own that - // lifecycle. Delegating HTTP init/cleanup to the SDK causes a double-free / - // use-after-free inside Aws::Http::CleanupHttp() at process exit, resulting - // in a SIGSEGV from the HDF5 VOL terminate callback. Disabling SDK-managed - // HTTP init/cleanup avoids the crash while leaving curl usable for the SDK. + // curl and OpenSSL global init/cleanup must be called exactly once per + // process and are not re-entrant. Python (or another loaded library such as + // h5py) may already own those lifecycles. Delegating init/cleanup to the SDK + // causes double-free / use-after-free crashes inside CleanupHttp() and + // CleanupCrypto() when the HDF5 VOL terminate callback fires at process exit, + // after the host process has already torn down those subsystems. Disabling + // SDK-managed init/cleanup for both avoids the crashes while leaving curl and + // OpenSSL usable for the SDK. g_sdk_options.httpOptions.initAndCleanupCurl = false; + g_sdk_options.cryptoOptions.initAndCleanupOpenSSL = false; std::set_terminate([]() { _exit(0); }); // Shutdown conflicts with Python's interpreter shutdown on macOS.