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.
This commit is contained in:
Alexandre Julliard 2002-06-04 17:48:41 +00:00
parent 78b041cf52
commit a061b84ee1
9 changed files with 259 additions and 178 deletions

View File

@ -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.

View File

@ -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;
}
/***********************************************************************

View File

@ -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 */

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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 );
}
@ -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)
{

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */