From f2c094caf38f402981b92a72820e2dbcb717e5dd Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 23 Apr 2026 15:01:32 +0300 Subject: [PATCH] [LIBWINE] Fix debug output synchronization Previously the debug macros printed file/line, class and message separately, which resulted in possible intermingling with other debug messages, e.g. from rosautotest. This caused random parse errors for testman. This is fixed by using a temp buffer for the prefix in rosfmt_default_dbg_vlog and then calling vDbgPrintExWithPrefix. Also make the __WINE_DPRINTF macro identical between GCC and MSVC. See ROSTESTS-178 --- dll/win32/comctl32/theming.c | 3 +- sdk/include/wine/debug.h | 57 ++++++-------------------------- sdk/lib/3rdparty/libwine/debug.c | 57 ++++++++++++++++++-------------- 3 files changed, 45 insertions(+), 72 deletions(-) diff --git a/dll/win32/comctl32/theming.c b/dll/win32/comctl32/theming.c index d66c7844532..5d93e148295 100644 --- a/dll/win32/comctl32/theming.c +++ b/dll/win32/comctl32/theming.c @@ -165,10 +165,11 @@ void THEMING_Initialize (void) { #ifdef __REACTOS__ /* r73803 */ WARN("Could not re-register class %s: %x\n", + debugstr_w (subclasses[i].className), GetLastError ()); #else ERR("Could not re-register class %s: %x\n", -#endif debugstr_w (subclasses[i].className), GetLastError ()); +#endif } else { diff --git a/sdk/include/wine/debug.h b/sdk/include/wine/debug.h index f1094dfb7f5..845400922ac 100644 --- a/sdk/include/wine/debug.h +++ b/sdk/include/wine/debug.h @@ -87,44 +87,20 @@ struct __wine_debug_channel #define __WINE_IS_DEBUG_ON(dbcl,dbch) \ (__WINE_GET_DEBUGGING##dbcl(dbch) && (__wine_dbg_get_channel_flags(dbch) & (1 << __WINE_DBCL##dbcl))) -#ifdef __GNUC__ - #define __WINE_DPRINTF(dbcl,dbch) \ do { if(__WINE_GET_DEBUGGING(dbcl,(dbch))) { \ struct __wine_debug_channel * const __dbch = (dbch); \ const enum __wine_debug_class __dbcl = __WINE_DBCL##dbcl; \ __WINE_DBG_LOG -#define __WINE_DBG_LOG(args...) \ - ros_dbg_log( __dbcl, __dbch, __RELFILE__, __FUNCTION__, __LINE__, args); } } while(0) - -#define __WINE_PRINTF_ATTR(fmt,args) /*__attribute__((format (printf,fmt,args)))*/ - - -#ifdef WINE_NO_TRACE_MSGS -#define WINE_TRACE(args...) do { } while(0) -#define WINE_TRACE_(ch) WINE_TRACE -#endif - -#ifdef WINE_NO_DEBUG_MSGS -#define WINE_WARN(args...) do { } while(0) -#define WINE_WARN_(ch) WINE_WARN -#define WINE_FIXME(args...) do { } while(0) -#define WINE_FIXME_(ch) WINE_FIXME -#endif - -#elif defined(__SUNPRO_C) - -#define __WINE_DPRINTF(dbcl,dbch) \ - do { if(__WINE_GET_DEBUGGING(dbcl,(dbch))) { \ - struct __wine_debug_channel * const __dbch = (dbch); \ - const enum __WINE_DEBUG_CLASS __dbcl = __WINE_DBCL##dbcl; \ - __WINE_DBG_LOG - #define __WINE_DBG_LOG(...) \ - wine_dbg_log( __dbcl, __dbch, __func__, __VA_ARGS__); } } while(0) + ros_dbg_log( __dbcl, __dbch, __RELFILE__, __FUNCTION__, __LINE__, __VA_ARGS__); } } while(0) +#if !defined(__REACTOS__) // (defined(__GNUC__) || defined(__clang__)) && (defined(__MINGW32__) || defined (_MSC_VER) || !defined(__WINE_USE_MSVCRT)) +#define __WINE_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args))) +#else #define __WINE_PRINTF_ATTR(fmt,args) +#endif #ifdef WINE_NO_TRACE_MSGS #define WINE_TRACE(...) do { } while(0) @@ -138,25 +114,14 @@ struct __wine_debug_channel #define WINE_FIXME_(ch) WINE_FIXME #endif -#else /* !__GNUC__ && !__SUNPRO_C */ - -#define __WINE_DPRINTF(dbcl,dbch) \ - (!__WINE_GET_DEBUGGING(dbcl,(dbch)) || \ - (ros_dbg_log(__WINE_DBCL##dbcl,(dbch),__RELFILE__,__FUNCTION__,__LINE__,"") == -1)) ? \ - (void)0 : (void)wine_dbg_printf - -#define __WINE_PRINTF_ATTR(fmt, args) - -#endif /* !__GNUC__ && !__SUNPRO_C */ - struct __wine_debug_functions { - char * (*get_temp_buffer)( size_t n ); - void (*release_temp_buffer)( char *buffer, size_t n ); - const char * (*dbgstr_an)( const char * s, int n ); - const char * (*dbgstr_wn)( const WCHAR *s, int n ); - int (*dbg_vprintf)( const char *format, va_list args ); - int (*dbg_vlog)( enum __wine_debug_class cls, struct __wine_debug_channel *channel, + char * (* const get_temp_buffer)( size_t n ); + void (* const release_temp_buffer)( char *buffer, size_t n ); + const char * (* const dbgstr_an)( const char * s, int n ); + const char * (* const dbgstr_wn)( const WCHAR *s, int n ); + int (* const dbg_vprintf)( const char *format, va_list args ); + int (* dbg_vlog)( enum __wine_debug_class cls, struct __wine_debug_channel *channel, const char *file, const char *function, const int line, const char *format, va_list args ); }; diff --git a/sdk/lib/3rdparty/libwine/debug.c b/sdk/lib/3rdparty/libwine/debug.c index f272bd1814a..9f8721ba204 100644 --- a/sdk/lib/3rdparty/libwine/debug.c +++ b/sdk/lib/3rdparty/libwine/debug.c @@ -158,7 +158,7 @@ static void parse_options( const char *str ) { for (i = 0; i < sizeof(debug_classes)/sizeof(debug_classes[0]); i++) { - int len = strlen(debug_classes[i]); + size_t len = strlen(debug_classes[i]); if (len != (p - opt)) continue; if (!memcmp( opt, debug_classes[i], len )) /* found it */ { @@ -356,7 +356,7 @@ static const char *default_dbgstr_an( const char *str, int n ) sprintf( res, "#%04x", LOWORD(str) ); return res; } - if (n == -1) n = strlen(str); + if (n == -1) n = (int)strlen(str); if (n < 0) n = 0; size = 10 + min( 300, n * 4 ); dst = res = funcs.get_temp_buffer( size ); @@ -466,63 +466,70 @@ static int default_dbg_vprintf( const char *format, va_list args ) static int winefmt_default_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_channel *channel, const char *file, const char *func, const int line, const char *format, va_list args ) { - int ret = 0; + char prefix[256]; + static const int max_len = sizeof(prefix); + int len = 0; if (TRACE_ON(pid)) - ret += wine_dbg_printf( "%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueProcess) ); - ret += wine_dbg_printf( "%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueThread) ); + len += _snprintf(prefix + len, max_len - len, "%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueProcess)); + len += wine_dbg_printf( "%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueThread)); if (cls < sizeof(debug_classes)/sizeof(debug_classes[0])) - ret += wine_dbg_printf( "%s:%s:%s ", debug_classes[cls], channel->name, func ); - if (format) - ret += funcs.dbg_vprintf( format, args ); - return ret; + len += _snprintf(prefix + len, max_len - len, "%s:%s:%s ", debug_classes[cls], channel->name, func); + + prefix[max_len - 1] = 0; + return vDbgPrintExWithPrefix(prefix, -1, 0, format, args); } + /* ReactOS format (default) */ static int rosfmt_default_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_channel *channel, const char *file, const char *func, const int line, const char *format, va_list args ) { - int ret = 0; + char prefix[256]; + static const int max_len = sizeof(prefix); + int len = 0; if (TRACE_ON(tid)) - ret += wine_dbg_printf( "%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueThread) ); + len += _snprintf(prefix + len, max_len - len, "%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueThread)); if (cls < sizeof(debug_classes)/sizeof(debug_classes[0])) - ret += wine_dbg_printf( "%s:", debug_classes[cls] ); + len += _snprintf(prefix + len, max_len - len, "%s:", debug_classes[cls]); if (file && line) - ret += wine_dbg_printf( "(%s:%d) ", file, line ); + len += _snprintf(prefix + len, max_len - len, "(%s:%d) ", file, line); else - ret += wine_dbg_printf( "%s:%s: ", channel->name, func ); + len += _snprintf(prefix + len, max_len - len, "%s:%s: ", channel->name, func); - if (format) - ret += funcs.dbg_vprintf( format, args ); - return ret; + prefix[max_len - 1] = 0; + return vDbgPrintExWithPrefix(prefix, -1, 0, format, args); } + /* Extended format */ static int extfmt_default_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_channel *channel, const char *file, const char *func, const int line, const char *format, va_list args ) { - int ret = 0; + char prefix[256]; + static const int max_len = sizeof(prefix); + int len = 0; if (TRACE_ON(pid) || TRACE_ON(tid)) { - ret += wine_dbg_printf( "[%04x:%04x]:", + len += _snprintf(prefix + len, max_len - len, "[%04x:%04x]:", (TRACE_ON(pid) ? HandleToULong(NtCurrentTeb()->ClientId.UniqueProcess) : 0), (TRACE_ON(tid) ? HandleToULong(NtCurrentTeb()->ClientId.UniqueThread) : 0) ); } if (cls < sizeof(debug_classes)/sizeof(debug_classes[0])) - ret += wine_dbg_printf( "%s:", debug_classes[cls] ); + len += _snprintf(prefix + len, max_len - len, "%s:", debug_classes[cls]); if (file && line) - ret += wine_dbg_printf( "(%s:%d):", file, line ); + len += _snprintf(prefix + len, max_len - len, "(%s:%d):", file, line); - ret += wine_dbg_printf( "%s:%s ", channel->name, func ); + if (len < max_len) + len += _snprintf(prefix + len, max_len - len, "%s:%s ", channel->name, func); - if (format) - ret += funcs.dbg_vprintf( format, args ); - return ret; + prefix[max_len - 1] = 0; + return vDbgPrintExWithPrefix(prefix, -1, 0, format, args); } /* wrappers to use the function pointers */