From 17aecf8a4cd5ba12489677fe6d1cd6ffe8966f82 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Mon, 3 Jul 2023 17:54:40 +0200 Subject: [PATCH] vkd3d: Flush debug log after sensitive crashes. We really need to make sure we get everything in the log. The important information might be hidden in the buffer. Especially relevant for indirect trace debug where we need buffered logs to keep FPS above fractional values. Signed-off-by: Hans-Kristian Arntzen --- include/private/vkd3d_debug.h | 1 + libs/vkd3d-common/debug.c | 36 ++++++++++++++++++++++++++++++----- libs/vkd3d/breadcrumbs.c | 1 + libs/vkd3d/debug_ring.c | 1 + 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/include/private/vkd3d_debug.h b/include/private/vkd3d_debug.h index 61976338a0..11192664b2 100644 --- a/include/private/vkd3d_debug.h +++ b/include/private/vkd3d_debug.h @@ -69,6 +69,7 @@ enum vkd3d_dbg_level vkd3d_dbg_get_level(enum vkd3d_dbg_channel channel); void vkd3d_dbg_printf(enum vkd3d_dbg_channel channel, enum vkd3d_dbg_level level, const char *function, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); +void vkd3d_dbg_flush(void); const char *vkd3d_dbg_sprintf(const char *fmt, ...) VKD3D_PRINTF_FUNC(1, 2); const char *vkd3d_dbg_vsprintf(const char *fmt, va_list args); diff --git a/libs/vkd3d-common/debug.c b/libs/vkd3d-common/debug.c index 23e84537b8..68c61388bc 100644 --- a/libs/vkd3d-common/debug.c +++ b/libs/vkd3d-common/debug.c @@ -146,9 +146,35 @@ enum vkd3d_dbg_level vkd3d_dbg_get_level(enum vkd3d_dbg_channel channel) return vkd3d_dbg_level[channel]; } +static spinlock_t vkd3d_debug_buffer_spin; + +void vkd3d_dbg_flush(void) +{ + if (vkd3d_dbg_buffer.buffer) + { + spinlock_acquire(&vkd3d_debug_buffer_spin); + if (vkd3d_dbg_buffer.offset) + { + if (vkd3d_log_file) + { + fwrite(vkd3d_dbg_buffer.buffer, 1, vkd3d_dbg_buffer.offset, vkd3d_log_file); + } + else + { + /* Binary vs text matters on Win32. + * Don't bother trying to be clever here reopening stdio files as O_BINARY, etc. */ + fputs(vkd3d_dbg_buffer.buffer, stderr); + } + + vkd3d_dbg_buffer.offset = 0; + fflush(vkd3d_log_file ? vkd3d_log_file : stderr); + } + spinlock_release(&vkd3d_debug_buffer_spin); + } +} + void vkd3d_dbg_printf(enum vkd3d_dbg_channel channel, enum vkd3d_dbg_level level, const char *function, const char *fmt, ...) { - static spinlock_t spin; unsigned int tid; FILE *log_file; va_list args; @@ -175,7 +201,7 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_channel channel, enum vkd3d_dbg_level level local_buffer_count = vsnprintf(local_buffer, sizeof(local_buffer), fmt, args); required_count = prefix_buffer_count + local_buffer_count; - spinlock_acquire(&spin); + spinlock_acquire(&vkd3d_debug_buffer_spin); if (vkd3d_dbg_buffer.offset + required_count > vkd3d_dbg_buffer.size) { if (vkd3d_log_file) @@ -206,7 +232,7 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_channel channel, enum vkd3d_dbg_level level fputs(prefix_buffer, log_file); fputs(local_buffer, log_file); } - spinlock_release(&spin); + spinlock_release(&vkd3d_debug_buffer_spin); } #ifdef _WIN32 else if (wine_log_output) @@ -228,10 +254,10 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_channel channel, enum vkd3d_dbg_level level #endif else { - spinlock_acquire(&spin); + spinlock_acquire(&vkd3d_debug_buffer_spin); fprintf(log_file, "%04x:%s:%s: ", tid, debug_level_names[level], function); vfprintf(log_file, fmt, args); - spinlock_release(&spin); + spinlock_release(&vkd3d_debug_buffer_spin); fflush(log_file); } va_end(args); diff --git a/libs/vkd3d/breadcrumbs.c b/libs/vkd3d/breadcrumbs.c index d9eb860250..20c7a12a16 100644 --- a/libs/vkd3d/breadcrumbs.c +++ b/libs/vkd3d/breadcrumbs.c @@ -578,6 +578,7 @@ void vkd3d_breadcrumb_tracer_report_device_lost(struct vkd3d_breadcrumb_tracer * } ERR("Done analyzing breadcrumbs ...\n"); + vkd3d_dbg_flush(); pthread_mutex_unlock(&global_report_lock); } diff --git a/libs/vkd3d/debug_ring.c b/libs/vkd3d/debug_ring.c index e7f851ac82..37a483fcb8 100644 --- a/libs/vkd3d/debug_ring.c +++ b/libs/vkd3d/debug_ring.c @@ -432,6 +432,7 @@ void *vkd3d_shader_debug_ring_thread_main(void *arg) } } INFO("Done fishing for clues ...\n"); + vkd3d_dbg_flush(); } return NULL;