winedbg: handling of several symbols with same name
eric pouech
eric.pouech at wanadoo.fr
Wed May 2 12:16:40 CDT 2001
this patch allow to pick up the right symbol from its name when several
symbols with the same name exist. If this happen, you will be prompted
for the symbol you want use.
one of the main reason for this is the case for import stubs. For
example
Wine-dbg>b CreateWindowExA
Many symbols with name 'CreateWindowExA', choose the one you want (<cr>
to abort):
[1]: 0x408c0fa8 (CreateWindowExA in libcomdlg32.so)
[2]: 0x4086d200 (CreateWindowExA in libcomctl32.so)
[3]: 0x407bdee0 (CreateWindowExA [win.c:1082] in libuser32.so)
[4]: 0x406176e0 (CreateWindowExA in libshell32.so)
=> 3
Breakpoint 3 at 0x406176e0 (CreateWindowExA in
libshell32.so)
the one you really want to debug is the third (in user32) not the import
stubs from comdlg32 or comctl32...
A+
--
---------------
Eric Pouech (http://perso.wanadoo.fr/eric.pouech/)
"The future will be better tomorrow", Vice President Dan Quayle
-------------- next part --------------
Name: wdbg_nsym
ChangeLog: Started handling of several symbols with the same name
fixed trampoline identification
GenDate: 2001/05/02 17:09:14 UTC
ModifiedFiles: debugger/break.c debugger/dbg.y debugger/debugger.h debugger/hash.c debugger/module.c debugger/winedbg.c
AddedFiles:
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/break.c,v
retrieving revision 1.25
diff -u -u -r1.25 break.c
--- debugger/break.c 2000/09/24 03:15:50 1.25
+++ debugger/break.c 2001/04/29 20:13:50
@@ -407,7 +407,7 @@
DEBUG_AddBreakpoint( &value, NULL );
}
- /***********************************************************************
+/***********************************************************************
* DEBUG_AddWatchpoint
*
* Add a watchpoint.
@@ -482,11 +482,11 @@
*
* Add a watchpoint from a symbol name (and eventually a line #)
*/
-void DEBUG_AddWatchpointFromId(const char *name, int lineno)
+void DEBUG_AddWatchpointFromId(const char *name)
{
DBG_VALUE value;
- if( DEBUG_GetSymbolValue(name, lineno, &value, TRUE) )
+ if( DEBUG_GetSymbolValue(name, -1, &value, TRUE) )
DEBUG_AddWatchpoint( &value, 1 );
else
DEBUG_Printf(DBG_CHN_MESG, "Unable to add watchpoint\n");
@@ -876,7 +876,7 @@
* FIXME - we need to check for things like thunks or trampolines,
* as the actual function may in fact have debug info.
*/
- if( ch == 0xe8 )
+ if ( ch == 0xe8 )
{
DEBUG_READ_MEM((void*)(instr + 1), &delta, sizeof(delta));
addr2 = addr;
Index: debugger/dbg.y
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/dbg.y,v
retrieving revision 1.42
diff -u -u -r1.42 dbg.y
--- debugger/dbg.y 2001/01/15 20:09:09 1.42
+++ debugger/dbg.y 2001/04/30 07:28:58
@@ -202,7 +202,7 @@
watch_command:
tWATCH '*' expr_addr tEOL { DEBUG_AddWatchpoint( &$3, 1 ); DEBUG_FreeExprMem(); }
- | tWATCH tIDENTIFIER tEOL { DEBUG_AddWatchpointFromId($2, -1); }
+ | tWATCH tIDENTIFIER tEOL { DEBUG_AddWatchpointFromId($2); }
info_command:
tINFO tBREAK tEOL { DEBUG_InfoBreakpoints(); }
Index: debugger/debugger.h
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/debugger.h,v
retrieving revision 1.20
diff -u -u -r1.20 debugger.h
--- debugger/debugger.h 2001/04/09 18:31:47 1.20
+++ debugger/debugger.h 2001/05/02 16:56:13
@@ -208,6 +208,7 @@
extern DWORD DEBUG_CurrTid;
extern DWORD DEBUG_CurrPid;
extern CONTEXT DEBUG_context;
+extern BOOL DEBUG_interactiveP;
#define DEBUG_READ_MEM(addr, buf, len) \
(ReadProcessMemory(DEBUG_CurrProcess->handle, (addr), (buf), (len), NULL))
@@ -230,7 +231,7 @@
char* module_name;
enum DbgInfoLoad dil;
enum DbgModuleType type;
- unsigned char main;
+ unsigned short main : 1;
short int dbg_index;
HMODULE handle;
struct tagMSC_DBG_INFO* msc_info;
@@ -255,7 +256,7 @@
extern void DEBUG_AddBreakpointFromId( const char *name, int lineno );
extern void DEBUG_AddBreakpointFromLineno( int lineno );
extern void DEBUG_AddWatchpoint( const DBG_VALUE *addr, int is_write );
-extern void DEBUG_AddWatchpointFromId( const char *name, int lineno );
+extern void DEBUG_AddWatchpointFromId( const char *name );
extern void DEBUG_DelBreakpoint( int num );
extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
extern void DEBUG_InfoBreakpoints(void);
@@ -314,8 +315,8 @@
const DBG_VALUE *addr,
const char *sourcefile,
int flags);
-extern BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
- DBG_VALUE *addr, int );
+extern int DEBUG_GetSymbolValue( const char * name, const int lineno,
+ DBG_VALUE *addr, int );
extern BOOL DEBUG_SetSymbolValue( const char * name, const DBG_VALUE *addr );
extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
struct name_hash ** rtn,
@@ -390,6 +391,7 @@
void* mod_addr, u_long size, HMODULE hmod);
extern DBG_MODULE* DEBUG_FindModuleByName(const char* name, enum DbgModuleType type);
extern DBG_MODULE* DEBUG_FindModuleByHandle(HANDLE handle, enum DbgModuleType type);
+extern DBG_MODULE* DEBUG_FindModuleByAddr(void* addr, enum DbgModuleType type);
extern DBG_MODULE* DEBUG_GetProcessMainModule(DBG_PROCESS* process);
extern DBG_MODULE* DEBUG_RegisterPEModule(HMODULE, u_long load_addr, u_long size,
const char* name);
Index: debugger/hash.c
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/hash.c,v
retrieving revision 1.20
diff -u -u -r1.20 hash.c
--- debugger/hash.c 2000/11/15 22:16:26 1.20
+++ debugger/hash.c 2001/05/02 12:47:33
@@ -181,14 +181,13 @@
* Add a symbol to the table.
*/
struct name_hash *
-DEBUG_AddSymbol( const char * name, const DBG_VALUE *value, const char * source,
- int flags)
+DEBUG_AddSymbol( const char * name, const DBG_VALUE *value,
+ const char * source, int flags)
{
struct name_hash * new;
struct name_hash *nh;
static char prev_source[PATH_MAX] = {'\0', };
static char * prev_duped_source = NULL;
- char * c;
int hash;
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
@@ -284,24 +283,17 @@
* calling things and the GCC way of calling things. In general we
* always want to step through.
*/
- if( source != NULL )
- {
- c = strrchr(source, '.');
- if( c != NULL && strcmp(c, ".s") == 0 )
- {
- c = strrchr(source, '/');
- if( c != NULL )
- {
- c++;
- if( (strcmp(c, "callfrom16.s") == 0)
- || (strcmp(c, "callto16.s") == 0)
- || (strcmp(c, "call32.s") == 0) )
- {
+ if ( source != NULL ) {
+ int len = strlen(source);
+
+ if (len > 2 && source[len-2] == '.' && source[len-1] == 's') {
+ char* c = strrchr(source - 2, '/');
+ if (c != NULL) {
+ if (strcmp(c + 1, "asmrelay.s") == 0)
new->flags |= SYM_TRAMPOLINE;
- }
- }
- }
- }
+ }
+ }
+ }
sortlist_valid = FALSE;
return new;
@@ -341,52 +333,79 @@
*
* Get the address of a named symbol.
*/
-BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
- DBG_VALUE *value, int bp_flag )
+static int DEBUG_GSV_Helper(const char* name, const int lineno,
+ DBG_VALUE* value, int num, int bp_flag)
{
- struct name_hash *nh;
-
- for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
- {
- if( (nh->flags & SYM_INVALID) != 0 )
- {
- continue;
- }
-
- if (!strcmp(nh->name, name)) break;
+ struct name_hash* nh;
+ int i = 0;
+ DBG_ADDR addr;
+
+ for (nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
+ {
+ if ((nh->flags & SYM_INVALID) != 0) continue;
+ if (!strcmp(nh->name, name) && DEBUG_GetLineNumberAddr( nh, lineno, &addr, bp_flag ))
+ {
+ if (i >= num) return num + 1;
+ value[i].addr = addr;
+ value[i].type = nh->value.type;
+ value[i].cookie = nh->value.cookie;
+ i++;
}
+ }
+ return i;
+}
- if (!nh && (name[0] != '_'))
- {
- char buffer[256];
+BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
+ DBG_VALUE *rtn, int bp_flag )
+{
+#define NUMDBGV 10
+ /* FIXME: NUMDBGV should be made variable */
+ DBG_VALUE value[NUMDBGV];
+ DBG_VALUE vtmp;
+ int num, i;
+
+ num = DEBUG_GSV_Helper(name, lineno, value, NUMDBGV, bp_flag);
+ if (!num && (name[0] != '_'))
+ {
+ char buffer[256];
- assert(strlen(name) < sizeof(buffer) - 2); /* one for '_', one for '\0' */
- buffer[0] = '_';
- strcpy(buffer+1, name);
- for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
- {
- if( (nh->flags & SYM_INVALID) != 0 )
- {
- continue;
- }
- if (!strcmp(nh->name, buffer)) break;
- }
- }
-
- /*
- * If we don't have anything here, then try and see if this
- * is a local symbol to the current stack frame. No matter
- * what, we have nothing more to do, so we let that function
- * decide what we ultimately return.
- */
- if (!nh)
- {
- return DEBUG_GetStackSymbolValue(name, value);
- }
-
- value->type = nh->value.type;
- value->cookie = nh->value.cookie;
- return DEBUG_GetLineNumberAddr( nh, lineno, &value->addr, bp_flag );
+ assert(strlen(name) < sizeof(buffer) - 2); /* one for '_', one for '\0' */
+ buffer[0] = '_';
+ strcpy(buffer + 1, name);
+ num = DEBUG_GSV_Helper(buffer, lineno, value, NUMDBGV, bp_flag);
+ }
+
+ /* now get the local symbols if any */
+ if (DEBUG_GetStackSymbolValue(name, &vtmp) && num < NUMDBGV)
+ {
+ value[num] = vtmp;
+ num++;
+ }
+
+ if (num == 0) {
+ return FALSE;
+ } else if (!DEBUG_interactiveP || num == 1) {
+ i = 0;
+ } else {
+ char* ptr;
+ if (num == NUMDBGV+1) {
+ DEBUG_Printf(DBG_CHN_MESG, "Too many addresses for symbol '%s', limiting the first %d\n", name, NUMDBGV);
+ num = NUMDBGV;
+ }
+ DEBUG_Printf(DBG_CHN_MESG, "Many symbols with name '%s', choose the one you want (<cr> to abort):\n", name);
+ for (i = 0; i < num; i++) {
+ DEBUG_Printf(DBG_CHN_MESG, "[%d]: ", i + 1);
+ DEBUG_PrintAddress( &value[i].addr, DEBUG_GetSelectorType(value[i].addr.seg), TRUE);
+ DEBUG_Printf(DBG_CHN_MESG, "\n");
+ }
+ do {
+ ptr = readline("=> ");
+ if (!*ptr) return FALSE;
+ i = atoi(ptr);
+ } while (i < 0 || i >= num);
+ }
+ *rtn = value[i];
+ return TRUE;
}
/***********************************************************************
@@ -495,6 +514,8 @@
int i;
char linebuff[16];
unsigned val;
+ DBG_MODULE* module;
+ char modbuf[256];
if( rtn != NULL )
{
@@ -666,6 +687,16 @@
}
}
+ module = DEBUG_FindModuleByAddr((void*)DEBUG_ToLinear(addr), DMT_UNKNOWN);
+ if (module) {
+ char* ptr = strrchr(module->module_name, '/');
+
+ if (!ptr++) ptr = module->module_name;
+ sprintf( modbuf, " in %s", ptr);
+ }
+ else
+ modbuf[0] = '\0';
+
if( (nearest->sourcefile != NULL) && (flag == TRUE)
&& (addr->off - nearest->value.addr.off < 0x100000) )
{
@@ -702,25 +733,25 @@
sourcefile = strrchr( nearest->sourcefile, '/' );
if (!sourcefile) sourcefile = nearest->sourcefile;
else sourcefile++;
-
+
if (addr->off == nearest->value.addr.off)
- sprintf( name_buffer, "%s%s [%s%s]", nearest->name,
- arglist, sourcefile, lineinfo);
+ sprintf( name_buffer, "%s%s [%s%s]%s", nearest->name,
+ arglist, sourcefile, lineinfo, modbuf);
else
- sprintf( name_buffer, "%s+0x%lx%s [%s%s]", nearest->name,
+ sprintf( name_buffer, "%s+0x%lx%s [%s%s]%s", nearest->name,
addr->off - nearest->value.addr.off,
- arglist, sourcefile, lineinfo );
+ arglist, sourcefile, lineinfo, modbuf );
}
else
{
if (addr->off == nearest->value.addr.off)
- sprintf( name_buffer, "%s%s", nearest->name, arglist);
+ sprintf( name_buffer, "%s%s%s", nearest->name, arglist, modbuf);
else {
if (addr->seg && (nearest->value.addr.seg!=addr->seg))
return NULL;
else
- sprintf( name_buffer, "%s+0x%lx%s", nearest->name,
- addr->off - nearest->value.addr.off, arglist);
+ sprintf( name_buffer, "%s+0x%lx%s%s", nearest->name,
+ addr->off - nearest->value.addr.off, arglist, modbuf);
}
}
return name_buffer;
@@ -732,7 +763,7 @@
*
* Read a symbol file into the hash table.
*/
-void DEBUG_ReadSymbolTable( const char * filename )
+void DEBUG_ReadSymbolTable( const char* filename )
{
FILE * symbolfile;
DBG_VALUE value;
Index: debugger/module.c
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/module.c,v
retrieving revision 1.11
diff -u -u -r1.11 module.c
--- debugger/module.c 2000/12/29 05:38:00 1.11
+++ debugger/module.c 2001/05/02 16:57:59
@@ -76,10 +76,13 @@
for (i = 0; i < DEBUG_CurrProcess->num_modules; i++) {
if ((type == DMT_UNKNOWN || type == amod[i]->type) &&
(u_long)addr >= (u_long)amod[i]->load_addr &&
- (!res || res->load_addr < amod[i]->load_addr))
- res = amod[i];
+ (u_long)addr < (u_long)amod[i]->load_addr + (u_long)amod[i]->size) {
+ /* amod[i] contains it... check against res now */
+ if (!res || res->load_addr < amod[i]->load_addr)
+ res = amod[i];
+ }
}
- return res;
+ return res;
}
/***********************************************************************
@@ -367,7 +370,7 @@
((names = DBG_alloc(sizeof(names[0]) * exports.NumberOfNames))) &&
DEBUG_READ_MEM_VERBOSE((void*)(base + (DWORD)exports.AddressOfNames),
names, sizeof(names[0]) * exports.NumberOfNames)) {
-
+
for (i = 0; i < exports.NumberOfNames; i++) {
if (!names[i] ||
!DEBUG_READ_MEM_VERBOSE((void*)(base + names[i]), bufstr, sizeof(bufstr)))
Index: debugger/winedbg.c
===================================================================
RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/winedbg.c,v
retrieving revision 1.31
diff -u -u -r1.31 winedbg.c
--- debugger/winedbg.c 2001/04/13 22:26:23 1.31
+++ debugger/winedbg.c 2001/04/29 20:12:10
@@ -28,6 +28,7 @@
DWORD DEBUG_CurrTid;
DWORD DEBUG_CurrPid;
CONTEXT DEBUG_context;
+BOOL DEBUG_interactiveP = FALSE;
int curr_frame = 0;
static char* DEBUG_LastCmdLine = NULL;
@@ -44,7 +45,7 @@
int DEBUG_Printf(int chn, const char* format, ...)
{
- char buf[1024];
+static char buf[4*1024];
va_list valist;
int len;
@@ -499,6 +500,7 @@
DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
if (DEBUG_ExceptionProlog(is_debug, force, rec->ExceptionCode)) {
+ DEBUG_interactiveP = TRUE;
while ((ret = DEBUG_Parser())) {
if (DEBUG_ValidateRegisters()) {
if (DEBUG_CurrThread->dbg_exec_mode != EXEC_PASS || first_chance)
@@ -506,6 +508,7 @@
DEBUG_Printf(DBG_CHN_MESG, "Cannot pass on last chance exception. You must use cont\n");
}
}
+ DEBUG_interactiveP = FALSE;
}
*cont = DEBUG_ExceptionEpilog();
@@ -861,7 +864,7 @@
}
DEBUG_Printf(DBG_CHN_MESG, "WineDbg starting... ");
-
+
if (argc == 3) {
HANDLE hEvent;
DWORD pid;
More information about the wine-patches
mailing list