From 9f75f7189935aeec55df79a5abbc3d2691ec5f7e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 3 Apr 2019 19:23:43 +0200 Subject: [PATCH] include: Make wine_dbgstr_an()/wine_dbgstr_wn() into inline functions. Signed-off-by: Alexandre Julliard --- dlls/ntdll/debugtools.c | 54 +++++------------------ dlls/ntdll/ntdll.spec | 3 ++ include/wine/debug.h | 96 ++++++++++++++++++++++++++++++++++++++++- libs/wine/debug.c | 4 ++ 4 files changed, 111 insertions(+), 46 deletions(-) diff --git a/dlls/ntdll/debugtools.c b/dlls/ntdll/debugtools.c index 4e2fd784f6b..42db30a5c2c 100644 --- a/dlls/ntdll/debugtools.c +++ b/dlls/ntdll/debugtools.c @@ -41,8 +41,6 @@ WINE_DECLARE_DEBUG_CHANNEL(pid); WINE_DECLARE_DEBUG_CHANNEL(timestamp); -static struct __wine_debug_functions default_funcs; - static BOOL init_done; static struct debug_info initial_info; /* debug info for initial thread */ @@ -77,49 +75,17 @@ static void release_temp_buffer( char *ptr, size_t size ) } /*********************************************************************** - * NTDLL_dbgstr_an + * __wine_dbg_strdup (NTDLL.@) */ -static const char *NTDLL_dbgstr_an( const char *src, int n ) +const char * __cdecl __wine_dbg_strdup( const char *str ) { - const char *res; struct debug_info *info = get_info(); - /* save current position to restore it on exception */ - char *old_pos = info->str_pos; + char *res = info->str_pos; + size_t n = strlen( str ) + 1; - __TRY - { - res = default_funcs.dbgstr_an( src, n ); - } - __EXCEPT_PAGE_FAULT - { - release_temp_buffer( old_pos, 0 ); - return "(invalid)"; - } - __ENDTRY - return res; -} - -/*********************************************************************** - * NTDLL_dbgstr_wn - */ -static const char *NTDLL_dbgstr_wn( const WCHAR *src, int n ) -{ - const char *res; - struct debug_info *info = get_info(); - /* save current position to restore it on exception */ - char *old_pos = info->str_pos; - - __TRY - { - res = default_funcs.dbgstr_wn( src, n ); - } - __EXCEPT_PAGE_FAULT - { - release_temp_buffer( old_pos, 0 ); - return "(invalid)"; - } - __ENDTRY - return res; + if (res + n > &info->strings[sizeof(info->strings)]) res = info->strings; + info->str_pos = res + n; + return strcpy( res, str ); } /*********************************************************************** @@ -195,8 +161,8 @@ static const struct __wine_debug_functions funcs = { get_temp_buffer, release_temp_buffer, - NTDLL_dbgstr_an, - NTDLL_dbgstr_wn, + wine_dbgstr_an, + wine_dbgstr_wn, NTDLL_dbg_vprintf, NTDLL_dbg_vlog }; @@ -210,5 +176,5 @@ void debug_init(void) if (!initial_info.out_pos) initial_info.out_pos = initial_info.output; ntdll_get_thread_data()->debug_info = &initial_info; init_done = TRUE; - __wine_dbg_set_functions( &funcs, &default_funcs, sizeof(funcs) ); + __wine_dbg_set_functions( &funcs, NULL, sizeof(funcs) ); } diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 233c4ef8797..762228936d2 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -1505,6 +1505,9 @@ @ cdecl wine_server_send_fd(long) @ cdecl __wine_make_process_system() +# Debugging +@ cdecl -norelay __wine_dbg_strdup(str) + # Virtual memory @ cdecl __wine_locked_recvmsg(long ptr long) diff --git a/include/wine/debug.h b/include/wine/debug.h index 07ac88d2647..65322d06f18 100644 --- a/include/wine/debug.h +++ b/include/wine/debug.h @@ -23,6 +23,9 @@ #include #include +#ifndef _NTSYSTEM_ +#include +#endif #ifndef GUID_DEFINED #include #endif @@ -157,6 +160,7 @@ extern int __wine_dbg_set_channel_flags( struct __wine_debug_channel *channel, unsigned char set, unsigned char clear ); extern void __wine_dbg_set_functions( const struct __wine_debug_functions *new_funcs, struct __wine_debug_functions *old_funcs, size_t size ); +extern const char * __cdecl __wine_dbg_strdup( const char *str ); /* * Exported definitions and macros @@ -165,14 +169,102 @@ extern void __wine_dbg_set_functions( const struct __wine_debug_functions *new_f /* These functions return a printable version of a string, including quotes. The string will be valid for some time, but not indefinitely as strings are re-used. */ -extern const char *wine_dbgstr_an( const char * s, int n ); -extern const char *wine_dbgstr_wn( const WCHAR *s, int n ); extern const char *wine_dbg_sprintf( const char *format, ... ) __WINE_PRINTF_ATTR(1,2); extern int wine_dbg_printf( const char *format, ... ) __WINE_PRINTF_ATTR(1,2); extern int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *ch, const char *func, const char *format, ... ) __WINE_PRINTF_ATTR(4,5); +static inline const char *wine_dbgstr_an( const char *str, int n ) +{ + static const char hex[16] = "0123456789abcdef"; + char buffer[300], *dst = buffer; + + if (!str) return "(null)"; + if (!((ULONG_PTR)str >> 16)) return wine_dbg_sprintf( "#%04x", LOWORD(str) ); +#ifndef _NTSYSTEM_ + if (IsBadStringPtrA( str, n )) return "(invalid)"; +#endif + if (n == -1) for (n = 0; str[n]; n++) ; + *dst++ = '"'; + while (n-- > 0 && dst <= buffer + sizeof(buffer) - 9) + { + unsigned char c = *str++; + switch (c) + { + case '\n': *dst++ = '\\'; *dst++ = 'n'; break; + case '\r': *dst++ = '\\'; *dst++ = 'r'; break; + case '\t': *dst++ = '\\'; *dst++ = 't'; break; + case '"': *dst++ = '\\'; *dst++ = '"'; break; + case '\\': *dst++ = '\\'; *dst++ = '\\'; break; + default: + if (c < ' ' || c >= 127) + { + *dst++ = '\\'; + *dst++ = 'x'; + *dst++ = hex[(c >> 4) & 0x0f]; + *dst++ = hex[c & 0x0f]; + } + else *dst++ = c; + } + } + *dst++ = '"'; + if (n > 0) + { + *dst++ = '.'; + *dst++ = '.'; + *dst++ = '.'; + } + *dst = 0; + return __wine_dbg_strdup( buffer ); +} + +static inline const char *wine_dbgstr_wn( const WCHAR *str, int n ) +{ + static const char hex[16] = "0123456789abcdef"; + char buffer[300], *dst = buffer; + + if (!str) return "(null)"; + if (!((ULONG_PTR)str >> 16)) return wine_dbg_sprintf( "#%04x", LOWORD(str) ); +#ifndef _NTSYSTEM_ + if (IsBadStringPtrW( str, n )) return "(invalid)"; +#endif + if (n == -1) for (n = 0; str[n]; n++) ; + *dst++ = 'L'; + *dst++ = '"'; + while (n-- > 0 && dst <= buffer + sizeof(buffer) - 10) + { + WCHAR c = *str++; + switch (c) + { + case '\n': *dst++ = '\\'; *dst++ = 'n'; break; + case '\r': *dst++ = '\\'; *dst++ = 'r'; break; + case '\t': *dst++ = '\\'; *dst++ = 't'; break; + case '"': *dst++ = '\\'; *dst++ = '"'; break; + case '\\': *dst++ = '\\'; *dst++ = '\\'; break; + default: + if (c < ' ' || c >= 127) + { + *dst++ = '\\'; + *dst++ = hex[(c >> 12) & 0x0f]; + *dst++ = hex[(c >> 8) & 0x0f]; + *dst++ = hex[(c >> 4) & 0x0f]; + *dst++ = hex[c & 0x0f]; + } + else *dst++ = c; + } + } + *dst++ = '"'; + if (n > 0) + { + *dst++ = '.'; + *dst++ = '.'; + *dst++ = '.'; + } + *dst = 0; + return __wine_dbg_strdup( buffer ); +} + static inline const char *wine_dbgstr_a( const char *s ) { return wine_dbgstr_an( s, -1 ); diff --git a/libs/wine/debug.c b/libs/wine/debug.c index ae12356cde6..0c3b4efafd3 100644 --- a/libs/wine/debug.c +++ b/libs/wine/debug.c @@ -30,6 +30,8 @@ # include #endif +#define wine_dbgstr_an wine_dbgstr_an_inline +#define wine_dbgstr_wn wine_dbgstr_wn_inline #include "wine/debug.h" #include "wine/library.h" @@ -420,11 +422,13 @@ static int default_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_ch /* wrappers to use the function pointers */ +#undef wine_dbgstr_an const char *wine_dbgstr_an( const char * s, int n ) { return funcs.dbgstr_an(s, n); } +#undef wine_dbgstr_wn const char *wine_dbgstr_wn( const WCHAR *s, int n ) { return funcs.dbgstr_wn(s, n);