Explicitly handle NULL Vulkan debug message IDs
The Vulkan spec states that the pMessageIdName for a debug message may
be NULL. We were previously passing it into a LogMessage (which wraps an
std::ostream) unchecked, but passing a NULL into an ostream is undefined
behavior. This was likely leading to crashes on some devices.
This patch updates the logging behavior to check for NULL and take a
different path if encountered to avoid triggering undefined behavior.
Bug: chromium:1497136
Change-Id: I431539dc21f51fa48bb754f5bc9c85acf2ce8f04
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/159040
Reviewed-by: Austin Eng <enga@chromium.org>
Auto-Submit: Brandon Jones <bajones@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
(cherry picked from commit 3a8735eb1fff33fe303b099623c870facb9f7268)
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/159032
Commit-Queue: Brandon Jones <bajones@chromium.org>
Kokoro: Brandon Jones <bajones@chromium.org>
diff --git a/src/dawn/native/vulkan/BackendVk.cpp b/src/dawn/native/vulkan/BackendVk.cpp
index 419c29a..6aba430 100644
--- a/src/dawn/native/vulkan/BackendVk.cpp
+++ b/src/dawn/native/vulkan/BackendVk.cpp
@@ -161,9 +161,10 @@
// Suppress validation errors that are known. Returns false in that case.
bool ShouldReportDebugMessage(const char* messageId, const char* message) {
- // pMessageIdName may be NULL
- if (messageId == nullptr) {
- return true;
+ // If a driver gives us a NULL pMessage (which would be a violation of the Vulkan spec)
+ // then ignore this message.
+ if (message == nullptr) {
+ return false;
}
// Some Vulkan drivers send "error" messages of "VK_SUCCESS" when zero devices are
@@ -175,6 +176,12 @@
return false;
}
+ // The Vulkan spec does allow pMessageIdName to be NULL, but it may still contain a valid
+ // message. Since we can't compare it with our skipped message list allow it through.
+ if (messageId == nullptr) {
+ return true;
+ }
+
for (const SkippedMessage& msg : kSkippedMessages) {
if (strstr(messageId, msg.messageId) != nullptr &&
strstr(message, msg.messageContents) != nullptr) {
@@ -184,6 +191,21 @@
return true;
}
+void LogCallbackData(LogSeverity severity,
+ const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData) {
+ LogMessage log = LogMessage(severity);
+
+ // pMessageIdName may be NULL, according to the Vulkan spec. Passing NULL into an ostream is
+ // undefined behavior, so we'll handle that scenario separately.
+ if (pCallbackData->pMessageIdName != nullptr) {
+ log << pCallbackData->pMessageIdName;
+ } else {
+ log << "nullptr";
+ }
+
+ log << ": " << pCallbackData->pMessage;
+}
+
VKAPI_ATTR VkBool32 VKAPI_CALL
OnDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT /* messageTypes */,
@@ -194,7 +216,7 @@
}
if (!(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)) {
- dawn::WarningLog() << pCallbackData->pMessageIdName << ": " << pCallbackData->pMessage;
+ LogCallbackData(LogSeverity::Warning, pCallbackData);
return VK_FALSE;
}
@@ -220,7 +242,7 @@
// We get to this line if no device was associated with the message. Crash so that the failure
// is loud and makes tests fail in Debug.
- dawn::ErrorLog() << pCallbackData->pMessageIdName << ": " << pCallbackData->pMessage;
+ LogCallbackData(LogSeverity::Error, pCallbackData);
DAWN_ASSERT(false);
return VK_FALSE;