From c764dd97a640388c5c48318640d3d23ea3b81569 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 3 Nov 2024 12:01:20 +0100 Subject: [PATCH] [util] Fix __wine_dbg_output crash with very long lines This sometimes happens with Vulkan validation layers enabled. --- src/util/log/log.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/util/log/log.cpp b/src/util/log/log.cpp index 6367f876c..2fca3eca9 100644 --- a/src/util/log/log.cpp +++ b/src/util/log/log.cpp @@ -78,10 +78,32 @@ namespace dxvk { if (!adjusted.empty()) { #ifdef _WIN32 - if (m_wineLogOutput) - m_wineLogOutput(adjusted.c_str()); - else + if (m_wineLogOutput) { + // __wine_dbg_output tries to buffer lines up to 1020 characters + // including null terminator, and will cause a hang if we submit + // anything longer than that even in consecutive calls. Work + // around this by splitting long lines into multiple lines. + constexpr size_t MaxDebugBufferLength = 1018; + + if (adjusted.size() <= MaxDebugBufferLength) { + m_wineLogOutput(adjusted.c_str()); + } else { + std::array buffer; + + for (size_t i = 0; i < adjusted.size(); i += MaxDebugBufferLength) { + size_t size = std::min(adjusted.size() - i, MaxDebugBufferLength); + + std::strncpy(buffer.data(), &adjusted[i], size); + if (buffer[size - 1u] != '\n') + buffer[size++] = '\n'; + + buffer[size] = '\0'; + m_wineLogOutput(buffer.data()); + } + } + } else { std::cerr << adjusted; + } #else std::cerr << adjusted; #endif