From a061b84ee1cebe8e76743c6e93cda7deee9e9ef0 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 4 Jun 2002 17:48:41 +0000 Subject: [PATCH] Moved specification of relay and snoop include/exclude functions to the config file. Changed spy config a bit to follow the same scheme. Moved debug option parsing routine into libwine. --- documentation/samples/config | 7 +- if1632/relay.c | 45 +++++++++- include/wine/library.h | 1 + library/debug.c | 57 ++++++++++++- misc/options.c | 104 ++--------------------- relay32/relay386.c | 154 ++++++++++++++++++++++++++--------- relay32/snoop.c | 5 +- scheduler/process.c | 3 + windows/spy.c | 61 ++++++-------- 9 files changed, 259 insertions(+), 178 deletions(-) diff --git a/documentation/samples/config b/documentation/samples/config index 589f667f5eb..92498e1573d 100644 --- a/documentation/samples/config +++ b/documentation/samples/config @@ -201,8 +201,11 @@ WINE REGISTRY Version 2 ;"read" = "0x779,0x379,0x280-0x2a0" ;"write" = "0x779,0x379,0x280-0x2a0" -[spy] -"Exclude" = "WM_SIZE;WM_TIMER;" +[Debug] +;"RelayExclude" = "RtlEnterCriticalSection;RtlLeaveCriticalSection" +;"RelayInclude" = "user32.CreateWindowA" +;"SnoopExclude" = "RtlEnterCriticalSection;RtlLeaveCriticalSection" +;"SpyExclude" = "WM_SIZE;WM_TIMER;" [registry] ;These are all booleans. Y/y/T/t/1 are true, N/n/F/f/0 are false. diff --git a/if1632/relay.c b/if1632/relay.c index 1263cc24b59..159411c0e0d 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -140,9 +140,48 @@ DWORD WINAPI CALL32_CBClientEx( FARPROC proc, LPWORD args, DWORD *esi, INT *nArg #endif -/* from relay32/relay386.c */ -extern char **debug_relay_excludelist,**debug_relay_includelist; -extern int RELAY_ShowDebugmsgRelay(const char *func); +/*********************************************************************** + * RELAY_ShowDebugmsgRelay + * + * Simple function to decide if a particular debugging message is + * wanted. + */ +static int RELAY_ShowDebugmsgRelay(const char *func) +{ + /* from relay32/relay386.c */ + extern const char **debug_relay_excludelist,**debug_relay_includelist; + + if(debug_relay_excludelist || debug_relay_includelist) { + const char *term = strchr(func, ':'); + const char **listitem; + int len, len2, itemlen, show; + + if(debug_relay_excludelist) { + show = 1; + listitem = debug_relay_excludelist; + } else { + show = 0; + listitem = debug_relay_includelist; + } + assert(term); + assert(strlen(term) > 2); + len = term - func; + len2 = strchr(func, '.') - func; + assert(len2 && len2 > 0 && len2 < 64); + term += 2; + for(; *listitem; listitem++) { + itemlen = strlen(*listitem); + if((itemlen == len && !strncasecmp(*listitem, func, len)) || + (itemlen == len2 && !strncasecmp(*listitem, func, len2)) || + !strcasecmp(*listitem, term)) { + show = !show; + break; + } + } + return show; + } + return 1; +} /*********************************************************************** diff --git a/include/wine/library.h b/include/wine/library.h index 515c4bb8007..b1d0407150a 100644 --- a/include/wine/library.h +++ b/include/wine/library.h @@ -50,6 +50,7 @@ extern int (*__wine_dbg_vlog)( int cls, const char *channel, const char *function, const char *format, va_list args ); extern void wine_dbg_add_option( const char *name, unsigned char set, unsigned char clear ); +extern int wine_dbg_parse_options( const char *str ); /* portability */ diff --git a/library/debug.c b/library/debug.c index 9bfa8786555..42926d053d7 100644 --- a/library/debug.c +++ b/library/debug.c @@ -53,6 +53,7 @@ struct debug_option static struct debug_option *first_option; static struct debug_option *last_option; +static const char * const debug_classes[] = { "fixme", "err", "warn", "trace" }; static int cmp_name( const void *p1, const void *p2 ) { @@ -140,6 +141,57 @@ void wine_dbg_add_option( const char *name, unsigned char set, unsigned char cle } } +/* parse a set of debugging option specifications and add them to the option list */ +int wine_dbg_parse_options( const char *str ) +{ + char *p, *opt, *next, *options; + int i, errors = 0; + + if (!(options = strdup(str))) return -1; + for (opt = options; opt; opt = next) + { + unsigned char set = 0, clear = 0; + + if ((next = strchr( opt, ',' ))) *next++ = 0; + + p = opt + strcspn( opt, "+-" ); + if (!p[0] || !p[1]) /* bad option, skip it */ + { + errors++; + continue; + } + + if (p > opt) + { + for (i = 0; i < sizeof(debug_classes)/sizeof(debug_classes[0]); i++) + { + int len = strlen(debug_classes[i]); + if (len != (p - opt)) continue; + if (!memcmp( opt, debug_classes[i], len )) /* found it */ + { + if (*p == '+') set |= 1 << i; + else clear |= 1 << i; + break; + } + } + if (i == sizeof(debug_classes)/sizeof(debug_classes[0])) /* bad class name, skip it */ + { + errors++; + continue; + } + } + else + { + if (*p == '+') set = ~0; + else clear = ~0; + } + p++; + if (!strcmp( p, "all" )) p = ""; /* empty string means all */ + wine_dbg_add_option( p, set, clear ); + } + free( options ); + return errors; +} /* varargs wrapper for __wine_dbg_vprintf */ int wine_dbg_printf( const char *format, ... ) @@ -318,11 +370,10 @@ static int default_dbg_vprintf( const char *format, va_list args ) static int default_dbg_vlog( int cls, const char *channel, const char *func, const char *format, va_list args ) { - static const char * const classes[] = { "fixme", "err", "warn", "trace" }; int ret = 0; - if (cls < sizeof(classes)/sizeof(classes[0])) - ret += wine_dbg_printf( "%s:%s:%s ", classes[cls], channel + 1, func ); + if (cls < sizeof(debug_classes)/sizeof(debug_classes[0])) + ret += wine_dbg_printf( "%s:%s:%s ", debug_classes[cls], channel + 1, func ); if (format) ret += __wine_dbg_vprintf( format, args ); return ret; diff --git a/misc/options.c b/misc/options.c index 1c6c9cd7dce..3421d097e6b 100644 --- a/misc/options.c +++ b/misc/options.c @@ -83,104 +83,14 @@ static void do_version( const char *arg ) static void do_debugmsg( const char *arg ) { - static const char * const debug_class_names[__WINE_DBCL_COUNT] = { "fixme", "err", "warn", "trace" }; - - char *opt, *options = strdup(arg); - int i; - /* defined in relay32/relay386.c */ - extern char **debug_relay_includelist; - extern char **debug_relay_excludelist; - /* defined in relay32/snoop.c */ - extern char **debug_snoop_includelist; - extern char **debug_snoop_excludelist; - - if (!(opt = strtok( options, "," ))) goto error; - do + if (wine_dbg_parse_options( arg )) { - unsigned char set = 0, clear = 0; - char *p = strchr( opt, '+' ); - if (!p) p = strchr( opt, '-' ); - if (!p || !p[1]) goto error; - if (p > opt) - { - for (i = 0; i < __WINE_DBCL_COUNT; i++) - { - int len = strlen(debug_class_names[i]); - if (len != (p - opt)) continue; - if (!memcmp( opt, debug_class_names[i], len )) /* found it */ - { - if (*p == '+') set |= 1 << i; - else clear |= 1 << i; - break; - } - } - if (i == __WINE_DBCL_COUNT) goto error; /* class name not found */ - } - else - { - if (*p == '+') set = ~0; - else clear = ~0; - if (!strncasecmp(p+1, "relay=", 6) || - !strncasecmp(p+1, "snoop=", 6)) - { - int i, l; - char *s, *s2, ***output, c; - - if (strchr(p,',')) - l=strchr(p,',')-p; - else - l=strlen(p); - set = ~0; - clear = 0; - output = (*p == '+') ? - ((*(p+1) == 'r') ? - &debug_relay_includelist : - &debug_snoop_includelist) : - ((*(p+1) == 'r') ? - &debug_relay_excludelist : - &debug_snoop_excludelist); - s = p + 7; - /* if there are n ':', there are n+1 modules, and we need - n+2 slots, last one being for the sentinel (NULL) */ - i = 2; - while((s = strchr(s, ':'))) i++, s++; - *output = malloc(sizeof(char **) * i); - i = 0; - s = p + 7; - while((s2 = strchr(s, ':'))) { - c = *s2; - *s2 = '\0'; - *((*output)+i) = _strupr(strdup(s)); - *s2 = c; - s = s2 + 1; - i++; - } - c = *(p + l); - *(p + l) = '\0'; - *((*output)+i) = _strupr(strdup(s)); - *(p + l) = c; - *((*output)+i+1) = NULL; - *(p + 6) = '\0'; - } - } - p++; - if (!strcmp( p, "all" )) p = ""; /* empty string means all */ - wine_dbg_add_option( p, set, clear ); - opt = strtok( NULL, "," ); - } while(opt); - - free( options ); - return; - - error: - MESSAGE("wine: Syntax: --debugmsg [class]+xxx,... or " - "-debugmsg [class]-xxx,...\n"); - MESSAGE("Example: --debugmsg +all,warn-heap\n" - " turn on all messages except warning heap messages\n"); - MESSAGE("Available message classes:\n"); - for( i = 0; i < __WINE_DBCL_COUNT; i++) MESSAGE( "%-9s", debug_class_names[i] ); - MESSAGE("\n\n"); - ExitProcess(1); + MESSAGE("%s: Syntax: --debugmsg [class]+xxx,... or -debugmsg [class]-xxx,...\n", argv0); + MESSAGE("Example: --debugmsg +all,warn-heap\n" + " turn on all messages except warning heap messages\n"); + MESSAGE("Available message classes: err, warn, fixme, trace\n\n"); + ExitProcess(1); + } } diff --git a/relay32/relay386.c b/relay32/relay386.c index 671061d4914..8cfb3c57778 100644 --- a/relay32/relay386.c +++ b/relay32/relay386.c @@ -26,52 +26,97 @@ #include #include "winnt.h" +#include "winreg.h" #include "stackframe.h" #include "module.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(relay); +WINE_DECLARE_DEBUG_CHANNEL(snoop); -char **debug_relay_excludelist = NULL, **debug_relay_includelist = NULL; +const char **debug_relay_excludelist = NULL; +const char **debug_relay_includelist = NULL; +const char **debug_snoop_excludelist = NULL; +const char **debug_snoop_includelist = NULL; /*********************************************************************** - * RELAY_ShowDebugmsgRelay + * build_list * - * Simple function to decide if a particular debugging message is - * wanted. Called from RELAY_CallFrom32 and from in if1632/relay.c + * Build a function list from a ';'-separated string. */ -int RELAY_ShowDebugmsgRelay(const char *func) { +static const char **build_list( const char *buffer ) +{ + int count = 1; + const char *p = buffer; + const char **ret; - if(debug_relay_excludelist || debug_relay_includelist) { - const char *term = strchr(func, ':'); - char **listitem; - int len, len2, itemlen, show; + while ((p = strchr( p, ';' ))) + { + count++; + p++; + } + /* allocate count+1 pointers, plus the space for a copy of the string */ + if ((ret = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(char*) + strlen(buffer) + 1 ))) + { + char *str = (char *)(ret + count + 1); + char *p = str; - if(debug_relay_excludelist) { - show = 1; - listitem = debug_relay_excludelist; - } else { - show = 0; - listitem = debug_relay_includelist; + strcpy( str, buffer ); + count = 0; + for (;;) + { + ret[count++] = p; + if (!(p = strchr( p, ';' ))) break; + *p++ = 0; + } + ret[count++] = NULL; } - assert(term); - assert(strlen(term) > 2); - len = term - func; - len2 = strchr(func, '.') - func; - assert(len2 && len2 > 0 && len2 < 64); - term += 2; - for(; *listitem; listitem++) { - itemlen = strlen(*listitem); - if((itemlen == len && !strncasecmp(*listitem, func, len)) || - (itemlen == len2 && !strncasecmp(*listitem, func, len2)) || - !strcasecmp(*listitem, term)) { - show = !show; - break; - } + return ret; +} + + +/*********************************************************************** + * RELAY_InitDebugLists + * + * Build the relay include/exclude function lists. + */ +void RELAY_InitDebugLists(void) +{ + char buffer[1024]; + HKEY hkey; + DWORD count, type; + + if (RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Debug", &hkey )) return; + + count = sizeof(buffer); + if (!RegQueryValueExA( hkey, "RelayInclude", NULL, &type, buffer, &count )) + { + TRACE("RelayInclude = %s\n", buffer ); + debug_relay_includelist = build_list( buffer ); } - return show; - } - return 1; + + count = sizeof(buffer); + if (!RegQueryValueExA( hkey, "RelayExclude", NULL, &type, buffer, &count )) + { + TRACE( "RelayExclude = %s\n", buffer ); + debug_relay_excludelist = build_list( buffer ); + } + + count = sizeof(buffer); + if (!RegQueryValueExA( hkey, "SnoopInclude", NULL, &type, buffer, &count )) + { + TRACE_(snoop)( "SnoopInclude = %s\n", buffer ); + debug_snoop_includelist = build_list( buffer ); + } + + count = sizeof(buffer); + if (!RegQueryValueExA( hkey, "SnoopExclude", NULL, &type, buffer, &count )) + { + TRACE_(snoop)( "SnoopExclude = %s\n", buffer ); + debug_snoop_excludelist = build_list( buffer ); + } + + RegCloseKey( hkey ); } @@ -88,6 +133,45 @@ typedef struct } DEBUG_ENTRY_POINT; +/*********************************************************************** + * check_relay_include + * + * Check if a given function must be included in the relay output. + */ +static BOOL check_relay_include( const char *module, const char *func ) +{ + const char **listitem; + BOOL show; + + if (!debug_relay_excludelist && !debug_relay_includelist) return TRUE; + if (debug_relay_excludelist) + { + show = TRUE; + listitem = debug_relay_excludelist; + } + else + { + show = FALSE; + listitem = debug_relay_includelist; + } + for(; *listitem; listitem++) + { + char *p = strchr( *listitem, '.' ); + if (p && p > *listitem) /* check module and function */ + { + int len = p - *listitem; + if (strncasecmp( *listitem, module, len-1 ) || module[len]) continue; + if (!strcmp( p + 1, func )) return !show; + } + else /* function only */ + { + if (!strcmp( *listitem, func )) return !show; + } + } + return show; +} + + /*********************************************************************** * find_exported_name * @@ -430,11 +514,7 @@ void RELAY_SetupDLL( const char *module ) if (debug->call != 0xe8 && debug->call != 0xe9) break; /* not a debug thunk at all */ if ((name = find_exported_name( module, exports, i + exports->Base ))) - { - char buffer[200]; - sprintf( buffer, "%s.%d: %s", dllname, i, name ); - on = RELAY_ShowDebugmsgRelay(buffer); - } + on = check_relay_include( dllname, name ); if (on) { diff --git a/relay32/snoop.c b/relay32/snoop.c index 59f8ba32cca..109a8cf90fb 100644 --- a/relay32/snoop.c +++ b/relay32/snoop.c @@ -42,7 +42,8 @@ static WINE_EXCEPTION_FILTER(page_fault) return EXCEPTION_CONTINUE_SEARCH; } -char **debug_snoop_excludelist = NULL, **debug_snoop_includelist = NULL; +extern const char **debug_snoop_excludelist; +extern const char **debug_snoop_includelist; #ifdef __i386__ @@ -113,7 +114,7 @@ static SNOOP_RETURNENTRIES *firstrets = NULL; int SNOOP_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname) { if(debug_snoop_excludelist || debug_snoop_includelist) { - char **listitem; + const char **listitem; char buf[80]; int len, len2, itemlen, show; diff --git a/scheduler/process.c b/scheduler/process.c index 84399432fa4..c0b58ae0673 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -46,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(process); WINE_DECLARE_DEBUG_CHANNEL(relay); +WINE_DECLARE_DEBUG_CHANNEL(snoop); WINE_DECLARE_DEBUG_CHANNEL(win32); struct _ENVDB; @@ -126,6 +127,7 @@ extern STARTUPINFOA current_startupinfo; /* scheduler/pthread.c */ extern void PTHREAD_init_done(void); +extern void RELAY_InitDebugLists(void); extern BOOL MAIN_MainInit(void); typedef WORD (WINAPI *pUserSignalProc)( UINT, DWORD, DWORD, HMODULE16 ); @@ -430,6 +432,7 @@ static BOOL process_init( char *argv[] ) OPTIONS_ParseOptions( !info_size ? argv : NULL ); ret = MAIN_MainInit(); + if (TRACE_ON(relay) || TRACE_ON(snoop)) RELAY_InitDebugLists(); return ret; } diff --git a/windows/spy.c b/windows/spy.c index 2467e426f4e..04665782b8e 100644 --- a/windows/spy.c +++ b/windows/spy.c @@ -2292,44 +2292,37 @@ int SPY_Init(void) if (!TRACE_ON(message)) return TRUE; indent_tls_index = TlsAlloc(); - buffer[0] = 0; - if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Spy", &hkey)) + if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Debug", &hkey)) { - DWORD type, count = sizeof(buffer); - RegQueryValueExA(hkey, "Include", 0, &type, buffer, &count); - RegCloseKey(hkey); - } - if (buffer[0] && strcmp( buffer, "INCLUDEALL" )) - { - TRACE("Include=%s\n", buffer ); - for (i = 0; i <= SPY_MAX_MSGNUM; i++) - SPY_Exclude[i] = (MessageTypeNames[i] && !strstr(buffer,MessageTypeNames[i])); - } + DWORD type, count = sizeof(buffer); - buffer[0] = 0; - if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Spy", &hkey)) - { - DWORD type, count = sizeof(buffer); - RegQueryValueExA(hkey, "Exclude", 0, &type, buffer, &count); - RegCloseKey(hkey); - } - if (buffer[0]) - { - TRACE("Exclude=%s\n", buffer ); - if (!strcmp( buffer, "EXCLUDEALL" )) - for (i = 0; i <= SPY_MAX_MSGNUM; i++) SPY_Exclude[i] = TRUE; - else + buffer[0] = 0; + if (!RegQueryValueExA(hkey, "SpyInclude", 0, &type, buffer, &count) && + strcmp( buffer, "INCLUDEALL" )) + { + TRACE("Include=%s\n", buffer ); for (i = 0; i <= SPY_MAX_MSGNUM; i++) - SPY_Exclude[i] = (MessageTypeNames[i] && strstr(buffer,MessageTypeNames[i])); - } + SPY_Exclude[i] = (MessageTypeNames[i] && !strstr(buffer,MessageTypeNames[i])); + } - SPY_ExcludeDWP = 0; - if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Spy", &hkey)) - { - DWORD type, count = sizeof(buffer); - if(!RegQueryValueExA(hkey, "ExcludeDWP", 0, &type, buffer, &count)) - SPY_ExcludeDWP = atoi(buffer); - RegCloseKey(hkey); + count = sizeof(buffer); + buffer[0] = 0; + if (!RegQueryValueExA(hkey, "SpyExclude", 0, &type, buffer, &count)) + { + TRACE("Exclude=%s\n", buffer ); + if (!strcmp( buffer, "EXCLUDEALL" )) + for (i = 0; i <= SPY_MAX_MSGNUM; i++) SPY_Exclude[i] = TRUE; + else + for (i = 0; i <= SPY_MAX_MSGNUM; i++) + SPY_Exclude[i] = (MessageTypeNames[i] && strstr(buffer,MessageTypeNames[i])); + } + + SPY_ExcludeDWP = 0; + count = sizeof(buffer); + if(!RegQueryValueExA(hkey, "SpyExcludeDWP", 0, &type, buffer, &count)) + SPY_ExcludeDWP = atoi(buffer); + + RegCloseKey(hkey); } /* find last good entry in spy notify array and save addr for b-search */