DetourModKit v3.2.1
Release Title: Loader-Lock Leak Path Hardening
Version: 3.2.1
Changelog:
A focused hardening patch on top of v3.2.0. Aligns Logger::shutdown_internal and ~ConfigWatcher with the same new (std::nothrow) discipline that HookManager::~HookManager adopted in v3.2.0, so all three loader-lock leak paths now uphold the noexcept destructor contract honestly under OOM. No API changes, no behavior changes on the success path; nothing on the per-frame hot path moves.
-
What's new in v3.2.1
- Honest
noexceptunder OOM in two more leak paths.Logger::shutdown_internaland~ConfigWatcherpreviously appended their detached state to astatic std::vectorviaemplace_back, which can throwstd::bad_allocand turn anoexceptdestructor intostd::terminate. Both paths now allocate a per-call heap cell vianew (std::nothrow)and leak the cell, mirroring the discipline introduced forHookManagerin v3.2.0. Issue #75. - Logger now pins the module on the leak path.
Logger::shutdown_internalwas missing thepin_current_module()call mandated by the project's leak-on-purpose discipline (AGENTS.md). DetachedAsyncLoggerwriter threads can now safely outlive the destructor without risking unmapped code pages. ~ConfigWatcherfalls back gracefully on OOM. When the heap cell allocation itself fails, the destructor callsm_impl.release()to leak the rawImplpointer without invoking~Impl(which would tear down the detachedStoppableWorkerunder loader lock). Strictly safer than the prioremplace_backpath, which terminated the process via thenoexceptguarantee onbad_alloc.
- Honest
-
Why this is a patch release
- No public API surface changes. Existing v3.2.0 callers compile and link unchanged.
- The fix only takes effect when the destructor runs under the Windows loader lock (
FreeLibraryfromDllMain), which is the same scenario already covered in v3.2.0 forHookManager. Normal teardown paths are untouched. - Both pre-existing patterns were safe in practice (the branch fires at most once per instance during DLL unload, where an OOM-induced
terminateis indistinguishable from OS teardown). The new code is "honest noexcept" cleanliness, not a bug fix in the everyday sense.
-
Tests
tests/test_logger.cppandtests/test_config_watcher.cppadd file-scopestatic_assertguards onis_nothrow_move_constructible_vfor the leak cell types, mirroring theis_nothrow_swappable_vpattern intests/test_hook_manager.cpp. A future change that breaks the noexcept contract onstd::shared_ptr<AsyncLogger>or default-deleterstd::unique_ptrwill fail to compile.- Existing
ConfigWatcherLoaderLockTest.MultipleLoaderLockTeardownsAreSafeexercises the new per-call heap cell path (the test does not introspect the storage, so the new pattern slots in transparently). - Full suite green: 1028/1028 on mingw-debug, 231/231 critical filtered tests on msvc-debug.
-
Docs
AGENTS.mdthread-safety table updated forLogger,ConfigWatcher, andHookManagerrows to describe the per-call heap cell pattern instead of the static vector.
-
Backwards compatibility
- All v3.2.0 APIs are unchanged. The fix is internal to two destructors.
- No
noexceptannotations changed. No header includes changed for consumers.
Full Changelog: v3.2.0...v3.2.1
Artifacts:
This release includes packages for different build environments. Both packages ensure library names are prefixed with lib for consistency (e.g., libDetourModKit.a, libDetourModKit.lib).
DetourModKit_MinGW_v3.2.1.zip: Built with MinGW (g++). ContainslibDetourModKit.a,libsafetyhook.a, headers, CMake config files. (Zydis & Zycore are statically linked into libsafetyhook.a).DetourModKit_MSVC_v3.2.1.zip: Built with MSVC (Visual Studio 2022). ContainslibDetourModKit.lib,libsafetyhook.lib(orsafetyhook.libif SafetyHook doesn't get the prefix), headers, CMake config files. (Zydis & Zycore are statically linked into libsafetyhook.lib/safetyhook.lib).
These packages are ready to be used by other CMake projects via find_package(DetourModKit).
See README for detailed usage instructions.