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:
parent
78b041cf52
commit
a061b84ee1
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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("%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:\n");
|
||||
for( i = 0; i < __WINE_DBCL_COUNT; i++) MESSAGE( "%-9s", debug_class_names[i] );
|
||||
MESSAGE("\n\n");
|
||||
MESSAGE("Available message classes: err, warn, fixme, trace\n\n");
|
||||
ExitProcess(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
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;
|
||||
ret[count++] = NULL;
|
||||
}
|
||||
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;
|
||||
|
||||
count = sizeof(buffer);
|
||||
if (!RegQueryValueExA( hkey, "RelayExclude", NULL, &type, buffer, &count ))
|
||||
{
|
||||
TRACE( "RelayExclude = %s\n", buffer );
|
||||
debug_relay_excludelist = build_list( buffer );
|
||||
}
|
||||
return 1;
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -2292,28 +2292,22 @@ 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" ))
|
||||
|
||||
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]));
|
||||
}
|
||||
|
||||
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])
|
||||
if (!RegQueryValueExA(hkey, "SpyExclude", 0, &type, buffer, &count))
|
||||
{
|
||||
TRACE("Exclude=%s\n", buffer );
|
||||
if (!strcmp( buffer, "EXCLUDEALL" ))
|
||||
|
@ -2324,11 +2318,10 @@ int SPY_Init(void)
|
|||
}
|
||||
|
||||
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))
|
||||
count = sizeof(buffer);
|
||||
if(!RegQueryValueExA(hkey, "SpyExcludeDWP", 0, &type, buffer, &count))
|
||||
SPY_ExcludeDWP = atoi(buffer);
|
||||
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue