For a while I've been running in to an issue with seemingly random crashes when allocating or freeing memory.
I think I've finally tracked it down to having multiple PhysicsWorld instances sharing a SingleFrameAllocator.
I know multiple worlds probably isn't a common use case, but here's what I've found, and potential solutions.
The problem is related to user code being able to cause allocations from the SingleFrameAllocator outside of PhysicsWorld::Update().
There may be multiple things that can trigger this, but most commonly, I'll use setTransform() and then testOverlap() or testCollision() and this will sometimes cause new elements to be added to mLostContactPairs via computeBroadPhase -> removeNonOverlappingPairs -> addLostContactPair.
Usually this is fine, because mLostContactPairs is processed in the next physics update before SingleFrameAllocator is cleared/reallocated.
But if another PhysicsWorld::Update() is called before then, the mLostContactPairs will be invalidated.
Here's an example timeline:
WORLD INSTANCE 1:
-PhysicsWorld::update()
-add lost contacts, process and clear lost contacts
-resetFrameAllocator()
-user code
-setTransform(), testOverlap(), causes mLostContactPairs.add() <--------------------------------------------------------
WORLD INSTANCE 2:
-PhysicsWorld::update()
-add lost contacts, process and clear lost contacts
-resetFrameAllocator() <--------------------------------------------------------
-user code
-move object, add lost contacts
WORLD INSTANCE 1:
-PhysicsWorld::update()
-lost contacts added in previous user code are now potentially being overwritten by other allocations,
or if the SingleFrameAllocator was resized, they will be in deallocated memory!
Potential solutions:
Always call PhysicsWorld::update() immediately AFTER any user code related to that instance, rather than before which I'm doing.
Have a separateSingleFrameAllocator for each PhysicsWorld instance.
Add a flag to redirect SingleFrameAllocator to a different allocator when outside of PhysicWorld::update()
Remove the resetFrameAllocator() from PhysicWorld::update() and call it manually after all updates are done.
No rush addressing this, I've implemented solution 3 as a workaround.
And apologies if this has been addressed already in develop branch, I haven't dug in deep enough to confirm if it's been fixed there.
Thanks again for your time and this excellent library!
Thanks a lot for taking the time to report this (with all the details). I don't have the time to improve this right now but I will take a look when I have some time.
Hi again!
For a while I've been running in to an issue with seemingly random crashes when allocating or freeing memory. I think I've finally tracked it down to having multiple
PhysicsWorld
instances sharing aSingleFrameAllocator
.I know multiple worlds probably isn't a common use case, but here's what I've found, and potential solutions.
The problem is related to user code being able to cause allocations from the
SingleFrameAllocator
outside ofPhysicsWorld::Update()
. There may be multiple things that can trigger this, but most commonly, I'll usesetTransform()
and thentestOverlap()
ortestCollision()
and this will sometimes cause new elements to be added tomLostContactPairs
via computeBroadPhase -> removeNonOverlappingPairs -> addLostContactPair. Usually this is fine, becausemLostContactPairs
is processed in the next physics update beforeSingleFrameAllocator
is cleared/reallocated. But if anotherPhysicsWorld::Update()
is called before then, themLostContactPairs
will be invalidated.Here's an example timeline:
Potential solutions:
PhysicsWorld::update()
immediately AFTER any user code related to that instance, rather than before which I'm doing.SingleFrameAllocator
for eachPhysicsWorld
instance.SingleFrameAllocator
to a different allocator when outside ofPhysicWorld::update()
resetFrameAllocator()
fromPhysicWorld::update()
and call it manually after all updates are done.No rush addressing this, I've implemented solution 3 as a workaround. And apologies if this has been addressed already in develop branch, I haven't dug in deep enough to confirm if it's been fixed there.
Thanks again for your time and this excellent library!