mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Fix] (MG_Impl, MG_Pipe): outlive the exit handlers - a frontend object destroyed by __run_exit_handlers reached the slot allocator, the resource tracker and the applier after their own destructors had run
This commit is contained in:
@@ -552,8 +552,11 @@ namespace MobileGL::MG_Pipe {
|
|||||||
// The monolith's one resource tracker, beside the state tracker, the CSO cache and the
|
// The monolith's one resource tracker, beside the state tracker, the CSO cache and the
|
||||||
// set-hash suppressor.
|
// set-hash suppressor.
|
||||||
inline MGPipeResourceTracker& MGPipeResourceTrackerInstance() {
|
inline MGPipeResourceTracker& MGPipeResourceTrackerInstance() {
|
||||||
static MGPipeResourceTracker tracker;
|
// NEVER DESTROYED, for MGPipeSlots()' reason (SlotAllocator.cpp): ~BufferObject reads
|
||||||
return tracker;
|
// and writes this tracker, and the objects that own the last reference to a
|
||||||
|
// BufferObject outlive every function-local static.
|
||||||
|
static MGPipeResourceTracker* tracker = new MGPipeResourceTracker();
|
||||||
|
return *tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -168,7 +168,15 @@ namespace MobileGL::MG_Pipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MGPipeSlotAllocator& MGPipeSlots() {
|
MGPipeSlotAllocator& MGPipeSlots() {
|
||||||
static MGPipeSlotAllocator allocator;
|
// NEVER DESTROYED, deliberately (one allocation for the life of the process). A
|
||||||
return allocator;
|
// frontend object's destructor reaches this allocator - ~BufferObject through
|
||||||
|
// MGPipeEmitResourceDestroyAndFree, ~VertexArrayObject through the death notice - and
|
||||||
|
// MG_Backend/MGPipe/PipeInputs.h's gPipeInputs holds SharedPtrs to those objects at
|
||||||
|
// namespace scope, so they are destroyed by __run_exit_handlers AFTER this
|
||||||
|
// function-local static would have been. A destroyed allocator then answers
|
||||||
|
// FindByLifetimeId out of a freed hash table and Free() writes into freed vectors -
|
||||||
|
// an exit-time heap corruption whose fatality depends only on the allocator's layout.
|
||||||
|
static MGPipeSlotAllocator* allocator = new MGPipeSlotAllocator();
|
||||||
|
return *allocator;
|
||||||
}
|
}
|
||||||
} // namespace MobileGL::MG_Pipe
|
} // namespace MobileGL::MG_Pipe
|
||||||
|
|||||||
@@ -377,7 +377,11 @@ namespace MobileGL::MG_Pipe {
|
|||||||
static_assert(kCapabilityCount <= 64,
|
static_assert(kCapabilityCount <= 64,
|
||||||
"ResidualValueBlock::CapabilityBits is a Uint64; 35 bits fit, 65 would not");
|
"ResidualValueBlock::CapabilityBits is a Uint64; 35 bits fit, 65 would not");
|
||||||
|
|
||||||
MGPipeApplierState g_applier{};
|
// A REFERENCE TO A NEVER-DESTROYED BLOCK, for MGPipeSlots()' reason
|
||||||
|
// (MG_Impl/Pipe/SlotAllocator.cpp): resource_destroy and delete_vertex_elements are
|
||||||
|
// raised from ~BufferObject / ~VertexArrayObject, and those objects are released by
|
||||||
|
// exit handlers that run after this translation unit's own globals are gone.
|
||||||
|
MGPipeApplierState& g_applier = *new MGPipeApplierState{};
|
||||||
|
|
||||||
// The installed handle-shaped resource table. Null until a backend registers one,
|
// The installed handle-shaped resource table. Null until a backend registers one,
|
||||||
// which is what makes the client half landable on its own: with nothing here every
|
// which is what makes the client half landable on its own: with nothing here every
|
||||||
|
|||||||
Reference in New Issue
Block a user