From 52c7534f411329bf0fa1365bf2e2401b72c157d5 Mon Sep 17 00:00:00 2001 From: Eric Pouech <eric.pouech@wanadoo.fr> Date: Thu, 3 May 2001 18:32:47 +0000 Subject: [PATCH] Started handling of several symbols with the same name. Fixed trampoline identification. --- debugger/break.c | 8 +-- debugger/dbg.y | 2 +- debugger/debugger.h | 10 +-- debugger/hash.c | 169 ++++++++++++++++++++++++++------------------ debugger/module.c | 11 +-- debugger/winedbg.c | 7 +- 6 files changed, 123 insertions(+), 84 deletions(-) diff --git a/debugger/break.c b/debugger/break.c index beabf4ce93d..88fb5edd310 100644 --- a/debugger/break.c +++ b/debugger/break.c @@ -407,7 +407,7 @@ void DEBUG_AddBreakpointFromLineno(int lineno) DEBUG_AddBreakpoint( &value, NULL ); } - /*********************************************************************** +/*********************************************************************** * DEBUG_AddWatchpoint * * Add a watchpoint. @@ -482,11 +482,11 @@ void DEBUG_AddWatchpoint( const DBG_VALUE *_value, BOOL is_write ) * * 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 @@ enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count ) * 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; diff --git a/debugger/dbg.y b/debugger/dbg.y index 3a086d83411..b014c7ca426 100644 --- a/debugger/dbg.y +++ b/debugger/dbg.y @@ -202,7 +202,7 @@ break_command: 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(); } diff --git a/debugger/debugger.h b/debugger/debugger.h index 9516d201b9a..a076afaa469 100644 --- a/debugger/debugger.h +++ b/debugger/debugger.h @@ -208,6 +208,7 @@ extern DBG_THREAD* DEBUG_CurrThread; 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 @@ typedef struct tagDBG_MODULE { 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_AddBreakpoint( const DBG_VALUE *addr, BOOL (*func)(void) ); 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 @@ extern struct name_hash * DEBUG_AddSymbol( const char *name, 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 @@ extern DBG_MODULE* DEBUG_AddModule(const char* name, enum DbgModuleType type, 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); diff --git a/debugger/hash.c b/debugger/hash.c index 7e170372bf4..204b53111e2 100644 --- a/debugger/hash.c +++ b/debugger/hash.c @@ -181,14 +181,13 @@ DEBUG_ResortSymbols(void) * 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 @@ DEBUG_AddSymbol( const char * name, const DBG_VALUE *value, const char * source, * 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 @@ BOOL DEBUG_Normalize(struct name_hash * nh ) * * 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) + 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( (nh->flags & SYM_INVALID) != 0 ) - { - continue; - } - - if (!strcmp(nh->name, name)) break; + 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); + 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; } - - value->type = nh->value.type; - value->cookie = nh->value.cookie; - return DEBUG_GetLineNumberAddr( nh, lineno, &value->addr, bp_flag ); + 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 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, int i; char linebuff[16]; unsigned val; + DBG_MODULE* module; + char modbuf[256]; if( rtn != NULL ) { @@ -666,6 +687,16 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, } } + 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 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, 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 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag, * * 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; diff --git a/debugger/module.c b/debugger/module.c index f16b95aba57..11220f96b58 100644 --- a/debugger/module.c +++ b/debugger/module.c @@ -76,10 +76,13 @@ DBG_MODULE* DEBUG_FindModuleByAddr(void* addr, enum DbgModuleType type) 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 @@ enum DbgInfoLoad DEBUG_RegisterPEDebugInfo(DBG_MODULE* wmod, HANDLE hFile, ((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))) diff --git a/debugger/winedbg.c b/debugger/winedbg.c index 686b587e945..b7ea1a604e6 100644 --- a/debugger/winedbg.c +++ b/debugger/winedbg.c @@ -28,6 +28,7 @@ DBG_THREAD* DEBUG_CurrThread = NULL; 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 @@ void DEBUG_Output(int chn, const char* buffer, int len) 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 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL 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 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL 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 @@ int DEBUG_main(int argc, char** argv) } DEBUG_Printf(DBG_CHN_MESG, "WineDbg starting... "); - + if (argc == 3) { HANDLE hEvent; DWORD pid; -- GitLab