Fix Vulkan leak if vkMapMemory fails
This introduces a macro DAWN_TRY_WITH_CLEANUP which allows
some code to be run before the early return.
Bug: chromium:1177332
Change-Id: I529c9ca6f2b0cf6ffd4bf85719a4e2a1c2552d1b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/42003
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
diff --git a/src/dawn_native/Error.h b/src/dawn_native/Error.h
index 4715c83..f7bc4a3 100644
--- a/src/dawn_native/Error.h
+++ b/src/dawn_native/Error.h
@@ -97,16 +97,20 @@
// When Errors aren't handled explicitly, calls to functions returning errors should be
// wrapped in an DAWN_TRY. It will return the error if any, otherwise keep executing
// the current function.
-#define DAWN_TRY(EXPR) \
- { \
- auto DAWN_LOCAL_VAR = EXPR; \
- if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) { \
- std::unique_ptr<::dawn_native::ErrorData> error = DAWN_LOCAL_VAR.AcquireError(); \
- error->AppendBacktrace(__FILE__, __func__, __LINE__); \
- return {std::move(error)}; \
- } \
- } \
- for (;;) \
+#define DAWN_TRY(EXPR) DAWN_TRY_WITH_CLEANUP(EXPR, {})
+
+#define DAWN_TRY_WITH_CLEANUP(EXPR, BODY) \
+ { \
+ auto DAWN_LOCAL_VAR = EXPR; \
+ if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) { \
+ {BODY} /* comment to force the formatter to insert a newline */ \
+ std::unique_ptr<::dawn_native::ErrorData> \
+ error = DAWN_LOCAL_VAR.AcquireError(); \
+ error->AppendBacktrace(__FILE__, __func__, __LINE__); \
+ return {std::move(error)}; \
+ } \
+ } \
+ for (;;) \
break
// DAWN_TRY_ASSIGN is the same as DAWN_TRY for ResultOrError and assigns the success value, if
diff --git a/src/dawn_native/vulkan/ResourceMemoryAllocatorVk.cpp b/src/dawn_native/vulkan/ResourceMemoryAllocatorVk.cpp
index f143c68..13ea9be 100644
--- a/src/dawn_native/vulkan/ResourceMemoryAllocatorVk.cpp
+++ b/src/dawn_native/vulkan/ResourceMemoryAllocatorVk.cpp
@@ -150,11 +150,14 @@
void* mappedPointer = nullptr;
if (mappable) {
- DAWN_TRY(
+ DAWN_TRY_WITH_CLEANUP(
CheckVkSuccess(mDevice->fn.MapMemory(mDevice->GetVkDevice(),
ToBackend(resourceHeap.get())->GetMemory(), 0,
size, 0, &mappedPointer),
- "vkMapMemory"));
+ "vkMapMemory"),
+ {
+ mAllocatorsPerType[memoryType]->DeallocateResourceHeap(std::move(resourceHeap));
+ });
}
AllocationInfo info;