Fix freed memory access due to DestroyObjects.

- Use a while loop to pop the list instead of iterating it and deleting at the same time.
- Adds regression tests to verify that the fix works.

Bug: chromium:1318792
Change-Id: I84fb494c64b07d3e1bd2b5b3af7cb9f82eee28b0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/88043
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
This commit is contained in:
Loko Kung
2022-04-28 02:54:43 +00:00
committed by Dawn LUCI CQ
parent e099b7cd8f
commit 928a7d1e93
2 changed files with 66 additions and 6 deletions

View File

@@ -287,10 +287,10 @@ namespace dawn::native {
void DeviceBase::DestroyObjects() {
// List of object types in reverse "dependency" order so we can iterate and delete the
// objects safely starting at leaf objects. We define dependent here such that if B has
// a ref to A, then B depends on A. We therefore try to destroy B before destroying A. Note
// that this only considers the immediate frontend dependencies, while backend objects could
// add complications and extra dependencies.
// objects safely. We define dependent here such that if B has a ref to A, then B depends on
// A. We therefore try to destroy B before destroying A. Note that this only considers the
// immediate frontend dependencies, while backend objects could add complications and extra
// dependencies.
//
// Note that AttachmentState is not an ApiObject so it cannot be eagerly destroyed. However,
// since AttachmentStates are cached by the device, objects that hold references to
@@ -330,8 +330,9 @@ namespace dawn::native {
const std::lock_guard<std::mutex> lock(objList.mutex);
objList.objects.MoveInto(&objects);
}
for (LinkNode<ApiObjectBase>* node : objects) {
node->value()->Destroy();
while (!objects.empty()) {
// The destroy call should also remove the object from the list.
objects.head()->value()->Destroy();
}
}