Symptom
Now and then a default-parallel run of streamlib-engine's lib tests dies with SIGABRT:
streamlib_engine-…: vendor/VulkanMemoryAllocator/include/vk_mem_alloc.h:6578: VmaDedicatedAllocationList::~VmaDedicatedAllocationList(): Assertion `false && "Unfreed dedicated allocations found!"' failed.
process didn't exit successfully: `…/streamlib_engine-…` (signal: 6, SIGABRT: process abort signal)
The binary dies mid-run, so it prints no failure summary.
To the best of our current knowledge, a VMA allocator is destroyed a VMA allocator or pool is destroyed while one of its dedicated allocations is still alive (VMA 3.3.0's VmaPool_T owns a VmaDedicatedAllocationList of its own, so vmaDestroyPool raises this same assertion; every export pool in HostVulkanDevice allocates DEDICATED_MEMORY). That means some test something — library code included, not only a test — drops a device, pool or allocator while an allocation outlives it, through a leak or a drop-order problem.
Where it bit
Found while verifying the #2245 fix on the NVIDIA rig (595.84, RTX 3090) on 2026-09-13. That fix removed the probe's concurrent eglTerminate, which caused the glibc heap-corruption aborts and hangs. This assertion is a separate defect that remains afterwards:
| Run (default parallel, with the #2245 fix) |
Result |
| engine lib test binary on its own, 20 runs |
20 completed, 0 aborts, 0 hangs |
cargo test --workspace --lib, 10 runs |
run 2 aborted inside the engine lib binary with this assertion; the other 9 completed |
The tests reporting just before the abort were in core::context::surface_export_staging, core::context::surface_store and core::context::gpu_context. No test had reported FAILED before it. The standalone and workspace runs build the engine lib binary with different feature unification, so the two rows are not strictly the same binary. One abort in 30 runs is too few to say whether the workspace build matters.
Because of this, #911's exit criterion of 10 consecutive clean --workspace --lib runs does not hold. It also stands in the way of gating the engine lib suite in CI (#1369).
Expected
Every engine lib test releases its allocations before its device and allocator drop. No default-parallel run ever trips VMA's teardown assertion. The fix belongs in whatever lets an allocation outlive its allocator. Serializing or skipping tests would only hide it.
Repro
- On the NVIDIA Linux rig, run
cargo test --workspace --lib (default parallelism) about 10 times, under a timeout.
- Expect roughly one run to end in the assertion above.
- Search that run's log for
Unfreed dedicated. The test … ok lines just before it show which tests were live.
- A backtrace from the abort (core dump or
gdb) would show which allocator's destructor fired. Running the engine lib binary alone may reproduce it less often.
Needs the physical rig?
Symptom
Now and then a default-parallel run of
streamlib-engine's lib tests dies with SIGABRT:The binary dies mid-run, so it prints no failure summary.
To the best of our current knowledge,
a VMA allocator is destroyeda VMA allocator or pool is destroyed while one of its dedicated allocations is still alive (VMA 3.3.0'sVmaPool_Towns aVmaDedicatedAllocationListof its own, sovmaDestroyPoolraises this same assertion; every export pool inHostVulkanDeviceallocatesDEDICATED_MEMORY). That meanssome testsomething — library code included, not only a test — drops a device, pool or allocator while an allocation outlives it, through a leak or a drop-order problem.Where it bit
Found while verifying the #2245 fix on the NVIDIA rig (595.84, RTX 3090) on 2026-09-13. That fix removed the probe's concurrent
eglTerminate, which caused the glibc heap-corruption aborts and hangs. This assertion is a separate defect that remains afterwards:cargo test --workspace --lib, 10 runsThe tests reporting just before the abort were in
core::context::surface_export_staging,core::context::surface_storeandcore::context::gpu_context. No test had reported FAILED before it. The standalone and workspace runs build the engine lib binary with different feature unification, so the two rows are not strictly the same binary. One abort in 30 runs is too few to say whether the workspace build matters.Because of this, #911's exit criterion of 10 consecutive clean
--workspace --libruns does not hold. It also stands in the way of gating the engine lib suite in CI (#1369).Expected
Every engine lib test releases its allocations before its device and allocator drop. No default-parallel run ever trips VMA's teardown assertion. The fix belongs in whatever lets an allocation outlive its allocator. Serializing or skipping tests would only hide it.
Repro
cargo test --workspace --lib(default parallelism) about 10 times, under a timeout.Unfreed dedicated. Thetest … oklines just before it show which tests were live.gdb) would show which allocator's destructor fired. Running the engine lib binary alone may reproduce it less often.Needs the physical rig?