Commit bbc5242f authored by Alexandre Julliard's avatar Alexandre Julliard

Fixed handling of relay and snoop include/exclude lists to behave as

documented (based on a patch by Rein Klazes).
parent 8f751bcb
...@@ -48,6 +48,13 @@ static const WCHAR **debug_snoop_excludelist; ...@@ -48,6 +48,13 @@ static const WCHAR **debug_snoop_excludelist;
static const WCHAR **debug_snoop_includelist; static const WCHAR **debug_snoop_includelist;
/* compare an ASCII and a Unicode string without depending on the current codepage */ /* compare an ASCII and a Unicode string without depending on the current codepage */
inline static int strcmpiAW( const char *strA, const WCHAR *strW )
{
while (*strA && (toupperW((unsigned char)*strA) == toupperW(*strW))) { strA++; strW++; }
return toupperW((unsigned char)*strA) - toupperW(*strW);
}
/* compare an ASCII and a Unicode string without depending on the current codepage */
inline static int strncmpiAW( const char *strA, const WCHAR *strW, int n ) inline static int strncmpiAW( const char *strA, const WCHAR *strW, int n )
{ {
int ret = 0; int ret = 0;
...@@ -156,41 +163,48 @@ void RELAY16_InitDebugLists(void) ...@@ -156,41 +163,48 @@ void RELAY16_InitDebugLists(void)
/*********************************************************************** /***********************************************************************
* check_list
*
* Check if a given module and function is in the list.
*/
static BOOL check_list( const char *module, int ordinal, const char *func, const WCHAR **list )
{
char ord_str[10];
sprintf( ord_str, "%d", ordinal );
for(; *list; list++)
{
const WCHAR *p = strrchrW( *list, '.' );
if (p && p > *list) /* check module and function */
{
int len = p - *list;
if (strncmpiAW( module, *list, len-1 ) || module[len]) continue;
if (p[1] == '*' && !p[2]) return TRUE;
if (!strcmpiAW( ord_str, p + 1 )) return TRUE;
if (func && !strcmpiAW( func, p + 1 )) return TRUE;
}
else /* function only */
{
if (func && !strcmpiAW( func, *list )) return TRUE;
}
}
return FALSE;
}
/***********************************************************************
* RELAY_ShowDebugmsgRelay * RELAY_ShowDebugmsgRelay
* *
* Simple function to decide if a particular debugging message is * Simple function to decide if a particular debugging message is
* wanted. * wanted.
*/ */
static int RELAY_ShowDebugmsgRelay(const char *func) static BOOL RELAY_ShowDebugmsgRelay(const char *module, int ordinal, const char *func)
{ {
if(debug_relay_excludelist || debug_relay_includelist) { if (debug_relay_excludelist && check_list( module, ordinal, func, debug_relay_excludelist ))
const char *term = strchr(func, ':'); return FALSE;
const WCHAR **listitem; if (debug_relay_includelist && !check_list( module, ordinal, func, debug_relay_includelist ))
int len, len2, itemlen, show; return FALSE;
return TRUE;
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 = strlenW(*listitem);
if (itemlen == len && !strncmpiAW(func, *listitem, len)) return !show;
if (itemlen == len2 && !strncmpiAW(func, *listitem, len2)) return !show;
if (!strncmpiAW(term, *listitem, itemlen) && !term[itemlen]) return !show;
}
return show;
}
return 1;
} }
...@@ -200,34 +214,13 @@ static int RELAY_ShowDebugmsgRelay(const char *func) ...@@ -200,34 +214,13 @@ static int RELAY_ShowDebugmsgRelay(const char *func)
* Simple function to decide if a particular debugging message is * Simple function to decide if a particular debugging message is
* wanted. * wanted.
*/ */
int SNOOP16_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname) int SNOOP16_ShowDebugmsgSnoop(const char *module, int ordinal, const char *func)
{ {
if(debug_snoop_excludelist || debug_snoop_includelist) { if (debug_snoop_excludelist && check_list( module, ordinal, func, debug_snoop_excludelist ))
const WCHAR **listitem; return FALSE;
char buf[80]; if (debug_snoop_includelist && !check_list( module, ordinal, func, debug_snoop_includelist ))
int len, len2, itemlen, show; return FALSE;
return TRUE;
if(debug_snoop_excludelist) {
show = 1;
listitem = debug_snoop_excludelist;
} else {
show = 0;
listitem = debug_snoop_includelist;
}
len = strlen(dll);
assert(len < 64);
sprintf(buf, "%s.%d", dll, ord);
len2 = strlen(buf);
for(; *listitem; listitem++)
{
itemlen = strlenW(*listitem);
if (itemlen == len && !strncmpiAW( buf, *listitem, len)) return !show;
if (itemlen == len2 && !strncmpiAW(buf, *listitem, len2)) return !show;
if (fname && !strncmpiAW(fname, *listitem, itemlen) && !fname[itemlen]) return !show;
}
return show;
}
return 1;
} }
...@@ -236,7 +229,7 @@ int SNOOP16_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname) ...@@ -236,7 +229,7 @@ int SNOOP16_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname)
* *
* Return the ordinal, name, and type info corresponding to a CS:IP address. * Return the ordinal, name, and type info corresponding to a CS:IP address.
*/ */
static const CALLFROM16 *get_entry_point( STACK16FRAME *frame, LPSTR name, WORD *pOrd ) static const CALLFROM16 *get_entry_point( STACK16FRAME *frame, LPSTR module, LPSTR func, WORD *pOrd )
{ {
WORD i, max_offset; WORD i, max_offset;
register BYTE *p; register BYTE *p;
...@@ -271,16 +264,16 @@ static const CALLFROM16 *get_entry_point( STACK16FRAME *frame, LPSTR name, WORD ...@@ -271,16 +264,16 @@ static const CALLFROM16 *get_entry_point( STACK16FRAME *frame, LPSTR name, WORD
/* (built-in modules have no non-resident table) */ /* (built-in modules have no non-resident table) */
p = (BYTE *)pModule + pModule->name_table; p = (BYTE *)pModule + pModule->name_table;
memcpy( module, p + 1, *p );
module[*p] = 0;
while (*p) while (*p)
{ {
p += *p + 1 + sizeof(WORD); p += *p + 1 + sizeof(WORD);
if (*(WORD *)(p + *p + 1) == *pOrd) break; if (*(WORD *)(p + *p + 1) == *pOrd) break;
} }
memcpy( func, p + 1, *p );
sprintf( name, "%.*s.%d: %.*s", func[*p] = 0;
*((BYTE *)pModule + pModule->name_table),
(char *)pModule + pModule->name_table + 1,
*pOrd, *p, (char *)(p + 1) );
/* Retrieve entry point call structure */ /* Retrieve entry point call structure */
p = MapSL( MAKESEGPTR( frame->module_cs, frame->callfrom_ip ) ); p = MapSL( MAKESEGPTR( frame->module_cs, frame->callfrom_ip ) );
...@@ -296,17 +289,17 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context ) ...@@ -296,17 +289,17 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context )
{ {
STACK16FRAME *frame; STACK16FRAME *frame;
WORD ordinal; WORD ordinal;
char *args16, funstr[80]; char *args16, module[10], func[64];
const CALLFROM16 *call; const CALLFROM16 *call;
int i; int i;
if (!TRACE_ON(relay)) return; if (!TRACE_ON(relay)) return;
frame = CURRENT_STACK16; frame = CURRENT_STACK16;
call = get_entry_point( frame, funstr, &ordinal ); call = get_entry_point( frame, module, func, &ordinal );
if (!call) return; /* happens for the two snoop register relays */ if (!call) return; /* happens for the two snoop register relays */
if (!RELAY_ShowDebugmsgRelay(funstr)) return; if (!RELAY_ShowDebugmsgRelay( module, ordinal, func )) return;
DPRINTF( "%04lx:Call %s(",GetCurrentThreadId(),funstr); DPRINTF( "%04lx:Call %s.%d: %s(",GetCurrentThreadId(), module, ordinal, func );
args16 = (char *)(frame + 1); args16 = (char *)(frame + 1);
if (call->lret == 0xcb66) /* cdecl */ if (call->lret == 0xcb66) /* cdecl */
...@@ -407,15 +400,15 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val ) ...@@ -407,15 +400,15 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val )
{ {
STACK16FRAME *frame; STACK16FRAME *frame;
WORD ordinal; WORD ordinal;
char funstr[80]; char module[10], func[64];
const CALLFROM16 *call; const CALLFROM16 *call;
if (!TRACE_ON(relay)) return; if (!TRACE_ON(relay)) return;
frame = CURRENT_STACK16; frame = CURRENT_STACK16;
call = get_entry_point( frame, funstr, &ordinal ); call = get_entry_point( frame, module, func, &ordinal );
if (!call) return; if (!call) return;
if (!RELAY_ShowDebugmsgRelay(funstr)) return; if (!RELAY_ShowDebugmsgRelay( module, ordinal, func )) return;
DPRINTF( "%04lx:Ret %s() ",GetCurrentThreadId(),funstr); DPRINTF( "%04lx:Ret %s.%d: %s() ", GetCurrentThreadId(), module, ordinal, func );
if (call->arg_types[0] & ARG_REGISTER) if (call->arg_types[0] & ARG_REGISTER)
{ {
......
...@@ -259,42 +259,47 @@ static WINE_EXCEPTION_FILTER(page_fault) ...@@ -259,42 +259,47 @@ static WINE_EXCEPTION_FILTER(page_fault)
} }
/*********************************************************************** /***********************************************************************
* check_relay_include * check_list
* *
* Check if a given function must be included in the relay output. * Check if a given module and function is in the list.
*/ */
static BOOL check_relay_include( const char *module, const char *func ) static BOOL check_list( const char *module, int ordinal, const char *func, const WCHAR **list )
{ {
const WCHAR **listitem; char ord_str[10];
BOOL show;
if (!debug_relay_excludelist && !debug_relay_includelist) return TRUE; sprintf( ord_str, "%d", ordinal );
if (debug_relay_excludelist) for(; *list; list++)
{
show = TRUE;
listitem = debug_relay_excludelist;
}
else
{ {
show = FALSE; const WCHAR *p = strrchrW( *list, '.' );
listitem = debug_relay_includelist; if (p && p > *list) /* check module and function */
}
for(; *listitem; listitem++)
{
WCHAR *p = strrchrW( *listitem, '.' );
if (p && p > *listitem) /* check module and function */
{ {
int len = p - *listitem; int len = p - *list;
if (strncmpiAW( module, *listitem, len-1 ) || module[len]) continue; if (strncmpiAW( module, *list, len-1 ) || module[len]) continue;
if (p[1] == '*' && !p[2]) return !show; if (p[1] == '*' && !p[2]) return TRUE;
if (!strcmpAW( func, p + 1 )) return !show; if (!strcmpAW( ord_str, p + 1 )) return TRUE;
if (func && !strcmpAW( func, p + 1 )) return TRUE;
} }
else /* function only */ else /* function only */
{ {
if (!strcmpAW( func, *listitem )) return !show; if (func && !strcmpAW( func, *list )) return TRUE;
} }
} }
return show; return FALSE;
}
/***********************************************************************
* check_relay_include
*
* Check if a given function must be included in the relay output.
*/
static BOOL check_relay_include( const char *module, int ordinal, const char *func )
{
if (debug_relay_excludelist && check_list( module, ordinal, func, debug_relay_excludelist ))
return FALSE;
if (debug_relay_includelist && !check_list( module, ordinal, func, debug_relay_includelist ))
return FALSE;
return TRUE;
} }
...@@ -734,8 +739,8 @@ void RELAY_SetupDLL( HMODULE module ) ...@@ -734,8 +739,8 @@ void RELAY_SetupDLL( HMODULE module )
if (!debug->call) continue; /* not a normal function */ if (!debug->call) continue; /* not a normal function */
if (debug->call != 0xe8 && debug->call != 0xe9) break; /* not a debug thunk at all */ if (debug->call != 0xe8 && debug->call != 0xe9) break; /* not a debug thunk at all */
if ((name = find_exported_name( module, exports, i + exports->Base ))) name = find_exported_name( module, exports, i + exports->Base );
on = check_relay_include( dllname, name ); on = check_relay_include( dllname, i + exports->Base, name );
if (on) if (on)
{ {
...@@ -763,35 +768,13 @@ void RELAY_SetupDLL( HMODULE module ) ...@@ -763,35 +768,13 @@ void RELAY_SetupDLL( HMODULE module )
* Simple function to decide if a particular debugging message is * Simple function to decide if a particular debugging message is
* wanted. * wanted.
*/ */
static int SNOOP_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname) static BOOL SNOOP_ShowDebugmsgSnoop(const char *module, int ordinal, const char *func)
{ {
if(debug_snoop_excludelist || debug_snoop_includelist) { if (debug_snoop_excludelist && check_list( module, ordinal, func, debug_snoop_excludelist ))
const WCHAR **listitem; return FALSE;
char buf[80]; if (debug_snoop_includelist && !check_list( module, ordinal, func, debug_snoop_includelist ))
int len, len2, itemlen, show; return FALSE;
return TRUE;
if(debug_snoop_excludelist) {
show = 1;
listitem = debug_snoop_excludelist;
} else {
show = 0;
listitem = debug_snoop_includelist;
}
len = strlen(dll);
assert(len < 64);
sprintf(buf, "%s.%d", dll, ord);
len2 = strlen(buf);
for(; *listitem; listitem++)
{
itemlen = strlenW(*listitem);
if((itemlen == len && !strncmpiAW( buf, *listitem, len)) ||
(itemlen == len2 && !strncmpiAW(buf, *listitem, len2)) ||
(fname && !strcmpAW(fname, *listitem)))
return !show;
}
return show;
}
return 1;
} }
......
.\" -*- nroff -*- .\" -*- nroff -*-
.TH WINE.CONF 5 "September 1, 2001" "Version 20010824" "Wine Configuration File" .TH WINE.CONF 5 "September 2003" "Version 20030911" "Wine Configuration File"
.SH NAME .SH NAME
wine.conf \- Wine configuration file wine.conf \- Wine configuration file
.SH DESCRIPTION .SH DESCRIPTION
...@@ -273,45 +273,44 @@ Used to specify which messages will be excluded from the logfile. ...@@ -273,45 +273,44 @@ Used to specify which messages will be excluded from the logfile.
default: none default: none
.br Used to specify which messages will be included in the logfile. .br Used to specify which messages will be included in the logfile.
.PP .PP
.I format: """RelayExclude""=""<function or dll.functions separated by semicolons>""" .I format: """RelayFromExclude""=""<module names separated by semicolons>"""
.br .br
default: none default: none
.br .br
Used to specify which functions will be excluded from a relay debug log. Used to specify a set of modules whose calls are excluded from a relay debug log.
.PP .PP
.I format: """RelayInclude""=""<function or dll.functions separated by semicolons>""" .I format: """RelayFromInclude""=""<module names separated by semicolons>"""
.br .br
default: include all functions default: include all modules
.br .br
Used to specify which functions will be included in a relay debug log. Used to specify the set of modules whose calls are included in a relay debug log.
.PP .PP
.I format: """RelayFromExclude""=""<module names separated by semicolons>""" .I format: """RelayExclude""=""<functions or dll.functions separated by semicolons>"""
.br .br
default: none default: none
.br .br
Used to specify a set of modules whose calls are excluded from a relay debug log. Used to specify which functions will be excluded from a relay debug log.
.PP .PP
.I format: """RelayFromInclude""=""<module names separated by semicolons>""" .I format: """RelayInclude""=""<functions or dll.functions separated by semicolons>"""
.br .br
default: include all modules default: include all functions
.br .br
Used to specify the set of modules whose calls are included in a relay debug log. Used to specify which functions will be included in a relay debug log.
.PP .PP
.I format: """SnoopExclude""=""<message names separated by semicolons>""" .I format: """SnoopExclude""=""<functions or dll.functions separated by semicolons>"""
.br .br
default: none default: none
.br .br
Used to specify which functions will be included in snoop debug log. Used to specify which functions will be excluded from the snoop debug log.
.PP .PP
.I format: """SnoopInclude""=""<message names separated by semicolons>""" .I format: """SnoopInclude""=""<functions or dll.functions separated by semicolons>"""
.br .br
default: include all functions default: include all functions
.br .br
Used to specify which functions will be included in snoop debug log. Used to specify which functions will be included in the snoop debug log.
.PP .PP
For Relay and Snoop <dllname>.* includes or excludes the whole dll. Exclude For Relay and Snoop <dllname>.* includes or excludes the whole dll. Exclude
entries overwrite Include entries. entries have priority over Include entries.
.br
.PP .PP
.B [Tweak.Layout] .B [Tweak.Layout]
.br .br
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment