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