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.
diff --git a/documentation/samples/config b/documentation/samples/config
index 589f667..92498e1 100644
--- a/documentation/samples/config
+++ b/documentation/samples/config
@@ -201,8 +201,11 @@
;"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 1263cc2..159411c 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -140,9 +140,48 @@
#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 515c4bb..b1d0407 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -50,6 +50,7 @@
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 9bfa878..42926d0 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -53,6 +53,7 @@
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 @@
}
}
+/* 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_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 1c6c9cd..3421d09 100644
--- a/misc/options.c
+++ b/misc/options.c
@@ -83,104 +83,14 @@
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 671061d..8cfb3c5 100644
--- a/relay32/relay386.c
+++ b/relay32/relay386.c
@@ -26,52 +26,97 @@
#include <stdio.h>
#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 );
}
@@ -89,6 +134,45 @@
/***********************************************************************
+ * 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
*
* Find the name of an exported function.
@@ -430,11 +514,7 @@
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 59f8ba3..109a8cf 100644
--- a/relay32/snoop.c
+++ b/relay32/snoop.c
@@ -42,7 +42,8 @@
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 @@
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 8439943..c0b58ae 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 @@
/* 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 @@
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 2467e42..0466578 100644
--- a/windows/spy.c
+++ b/windows/spy.c
@@ -2292,44 +2292,37 @@
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 */