From 71189b52245e6382d36cf211732084acea662193 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Tue, 25 Jul 2000 12:51:56 +0000 Subject: [PATCH] fixed a number of long standing bugs: - segmented expressions didn't display correctly - using dynamic size array for nested types parsing - correct display of source code after a crash factorized some code --- debugger/break.c | 24 ++------------- debugger/debugger.h | 29 ++++++++++-------- debugger/expr.c | 3 +- debugger/memory.c | 83 ++++++++++++++++++++++++-------------------------- debugger/source.c | 88 ++++++++++++----------------------------------------- debugger/stabs.c | 22 +++++++------- debugger/winedbg.c | 12 +++++--- 7 files changed, 99 insertions(+), 162 deletions(-) diff --git a/debugger/break.c b/debugger/break.c index 9209713fc04..bf16d474a0d 100644 --- a/debugger/break.c +++ b/debugger/break.c @@ -326,27 +326,9 @@ void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) ) { DBG_VALUE value = *_value; int num; - unsigned int seg2; BYTE ch; - assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST); - -#ifdef __i386__ - DEBUG_FixAddress( &value.addr, DEBUG_context.SegCs ); -#endif - - if( value.type != NULL && value.type == DEBUG_TypeIntConst ) - { - /* - * We know that we have the actual offset stored somewhere - * else in 32-bit space. Grab it, and we - * should be all set. - */ - seg2 = value.addr.seg; - value.addr.seg = 0; - value.addr.off = DEBUG_GetExprValue(&value, NULL); - value.addr.seg = seg2; - } + if( !DEBUG_GrabAddress(&value, TRUE) ) return; if ((num = DEBUG_FindBreakpoint(&value.addr, DBG_BREAK)) >= 1) { @@ -558,7 +540,7 @@ static int DEBUG_FindTriggeredWatchpoint(LPDWORD oldval) int i; /* Method 1 => get triggered watchpoint from context (doesn't work on Linux - * 2.2.x) + * 2.2.x). This should be fixed in >= 2.2.16 */ for (i = 0; i < next_bp; i++) { @@ -746,7 +728,7 @@ BOOL DEBUG_ShouldContinue( DWORD code, enum exec_mode mode, int * count ) if (!DEBUG_ShallBreak(wpnum)) return TRUE; #ifdef __i386__ - addrlen = !addr.seg? 32 : DEBUG_GetSelectorType( addr.seg ); + if (addr.seg) addrlen = DEBUG_GetSelectorType( addr.seg ); #endif DEBUG_Printf(DBG_CHN_MESG, "Stopped on watchpoint %d at ", wpnum); syminfo = DEBUG_PrintAddress( &addr, addrlen, TRUE ); diff --git a/debugger/debugger.h b/debugger/debugger.h index 7776c47aef3..e64c5672013 100644 --- a/debugger/debugger.h +++ b/debugger/debugger.h @@ -53,14 +53,17 @@ typedef struct DWORD off; } DBG_ADDR; -#define DV_TARGET 0xF00D -#define DV_HOST 0x50DA -#define DV_INVALID 0x0000 - typedef struct { struct datatype* type; int cookie; /* DV_??? */ +/* DV_TARGET references an address in debugger's address space, whereas DV_HOST + * references the debuggee address space + */ +# define DV_TARGET 0xF00D +# define DV_HOST 0x50DA +# define DV_INVALID 0x0000 + DBG_ADDR addr; } DBG_VALUE; @@ -353,6 +356,7 @@ extern void DEBUG_InvalAddr( const DBG_ADDR* addr ); extern void DEBUG_InvalLinAddr( void* addr ); extern DWORD DEBUG_ToLinear( const DBG_ADDR *address ); extern void DEBUG_GetCurrentAddress( DBG_ADDR * ); +extern BOOL DEBUG_GrabAddress( DBG_VALUE* value, BOOL fromCode ); #ifdef __i386__ extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def ); extern BOOL DEBUG_FixSegment( DBG_ADDR* addr ); @@ -381,6 +385,15 @@ extern void DEBUG_InitCVDataTypes(void); extern void DEBUG_InfoRegisters(void); extern BOOL DEBUG_ValidateRegisters(void); + /* debugger/source.c */ +extern void DEBUG_ShowDir(void); +extern void DEBUG_AddPath(const char * path); +extern void DEBUG_List(struct list_id * line1, struct list_id * line2, + int delta); +extern void DEBUG_NukePath(void); +extern void DEBUG_Disassemble(const DBG_VALUE *, const DBG_VALUE*, int offset); +extern BOOL DEBUG_DisassembleInstruction(DBG_ADDR *addr); + /* debugger/stack.c */ extern void DEBUG_InfoStack(void); extern void DEBUG_BackTrace(BOOL noisy); @@ -425,14 +438,6 @@ extern struct datatype * DEBUG_TypeCast(enum debug_type, const char *); extern int DEBUG_PrintTypeCast(const struct datatype *); extern int DEBUG_PrintType( const DBG_VALUE* addr ); - /* debugger/source.c */ -extern void DEBUG_ShowDir(void); -extern void DEBUG_AddPath(const char * path); -extern void DEBUG_List(struct list_id * line1, struct list_id * line2, - int delta); -extern void DEBUG_NukePath(void); -extern void DEBUG_Disassemble( const DBG_VALUE *, const DBG_VALUE*, int offset ); - /* debugger/winedbg.c */ #define DBG_CHN_MESG 1 #define DBG_CHN_ERR 2 diff --git a/debugger/expr.c b/debugger/expr.c index 4cd109b145b..29262ef7ced 100644 --- a/debugger/expr.c +++ b/debugger/expr.c @@ -510,8 +510,9 @@ DBG_VALUE DEBUG_EvalExpr(struct expr * exp) break; case EXP_OP_SEG: rtn.cookie = DV_TARGET; + rtn.type = NULL; rtn.addr.seg = VAL(exp1); - exp->un.binop.result = VAL(exp2); + rtn.addr.off = VAL(exp2); #ifdef __i386__ DEBUG_FixSegment(&rtn.addr); #endif diff --git a/debugger/memory.c b/debugger/memory.c index 645a680c954..6f7083ca288 100644 --- a/debugger/memory.c +++ b/debugger/memory.c @@ -206,26 +206,18 @@ void DEBUG_WriteMemory( const DBG_VALUE* val, int value ) } } - /*********************************************************************** - * DEBUG_ExamineMemory + * DEBUG_GrabAddress * - * Implementation of the 'x' command. + * Get the address from a value */ -void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format ) +BOOL DEBUG_GrabAddress( DBG_VALUE* value, BOOL fromCode ) { - DBG_VALUE value = *_value; - int i; - unsigned char * pnt; - struct datatype * testtype; - - assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST); + assert(value->cookie == DV_TARGET || value->cookie == DV_HOST); #ifdef __i386__ - DEBUG_FixAddress( &value.addr, - (format == 'i') ? - DEBUG_context.SegCs : - DEBUG_context.SegDs ); + DEBUG_FixAddress( &value->addr, + (fromCode) ? DEBUG_context.SegCs : DEBUG_context.SegDs); #endif /* @@ -233,35 +225,44 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format ) * reading. We will use the same segment as what we have already, * and hope that this is a sensible thing to do. */ - if( value.type != NULL ) - { - if( value.type == DEBUG_TypeIntConst ) - { + if (value->type != NULL) { + if (value->type == DEBUG_TypeIntConst) { /* * We know that we have the actual offset stored somewhere * else in 32-bit space. Grab it, and we * should be all set. */ - unsigned int seg2 = value.addr.seg; - value.addr.seg = 0; - value.addr.off = DEBUG_GetExprValue(&value, NULL); - value.addr.seg = seg2; - } - else - { - if (DEBUG_TypeDerefPointer(&value, &testtype) == 0) - return; - if( testtype != NULL || value.type == DEBUG_TypeIntConst ) - { - value.addr.off = DEBUG_GetExprValue(&value, NULL); - } - } - } - else if (!value.addr.seg && !value.addr.off) - { - DEBUG_Printf(DBG_CHN_MESG,"Invalid expression\n"); - return; + unsigned int seg2 = value->addr.seg; + value->addr.seg = 0; + value->addr.off = DEBUG_GetExprValue(value, NULL); + value->addr.seg = seg2; + } else { + struct datatype * testtype; + + if (DEBUG_TypeDerefPointer(value, &testtype) == 0) + return FALSE; + if (testtype != NULL || value->type == DEBUG_TypeIntConst) + value->addr.off = DEBUG_GetExprValue(value, NULL); + } + } else if (!value->addr.seg && !value->addr.off) { + DEBUG_Printf(DBG_CHN_MESG,"Invalid expression\n"); + return FALSE; } + return TRUE; +} + +/*********************************************************************** + * DEBUG_ExamineMemory + * + * Implementation of the 'x' command. + */ +void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format ) +{ + DBG_VALUE value = *_value; + int i; + unsigned char * pnt; + + if (!DEBUG_GrabAddress(&value, (format == 'i'))) return; if (format != 'i' && count > 1) { @@ -301,13 +302,7 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format ) return; } case 'i': - while (count--) - { - DEBUG_PrintAddress( &value.addr, DEBUG_CurrThread->dbg_mode, TRUE ); - DEBUG_Printf(DBG_CHN_MESG,": "); - DEBUG_Disasm( &value.addr, TRUE ); - DEBUG_Printf(DBG_CHN_MESG,"\n"); - } + while (count-- && DEBUG_DisassembleInstruction( &value.addr )); return; #define DO_DUMP2(_t,_l,_f,_vv) { \ _t _v; \ diff --git a/debugger/source.c b/debugger/source.c index 595ff5b73a2..7ec9020706a 100644 --- a/debugger/source.c +++ b/debugger/source.c @@ -187,7 +187,7 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end) /* * Still couldn't find it. Ask user for path to add. */ - sprintf(zbuf, "Enter path to file %s: ", sourcefile); + sprintf(zbuf, "Enter path to file '%s': ", sourcefile); lstrcpynA(tmppath, readline(zbuf), sizeof(tmppath)); if( tmppath[strlen(tmppath)-1] == '\n' ) @@ -425,56 +425,21 @@ DEBUG_List(struct list_id * source1, struct list_id * source2, DBG_ADDR DEBUG_LastDisassemble={0,0}; -static int -_disassemble(DBG_ADDR *addr) +BOOL DEBUG_DisassembleInstruction(DBG_ADDR *addr) { - char ch; - - DEBUG_PrintAddress( addr, DEBUG_CurrThread->dbg_mode, TRUE ); - DEBUG_Printf(DBG_CHN_MESG,": "); - if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(addr), &ch, sizeof(ch))) return 0; - DEBUG_Disasm( addr, TRUE ); + char ch; + BOOL ret = TRUE; + + DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, TRUE); + DEBUG_Printf(DBG_CHN_MESG, ": "); + if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(addr), &ch, sizeof(ch))) { + DEBUG_Printf(DBG_CHN_MESG, "-- no code --"); + ret = FALSE; + } else { + DEBUG_Disasm(addr, TRUE); + } DEBUG_Printf(DBG_CHN_MESG,"\n"); - return 1; -} - -void -_disassemble_fixaddr(DBG_VALUE *value) { - DWORD seg2; - struct datatype *testtype; - - assert(value->cookie == DV_TARGET || value->cookie == DV_HOST); - -#ifdef __i386__ - DEBUG_FixAddress(&value->addr, DEBUG_context.SegCs); -#endif - - if( value->type != NULL ) - { - if( value->type == DEBUG_TypeIntConst ) - { - /* - * We know that we have the actual offset stored somewhere - * else in 32-bit space. Grab it, and we - * should be all set. - */ - seg2 = value->addr.seg; - value->addr.seg = 0; - value->addr.off = DEBUG_GetExprValue(value, NULL); - value->addr.seg = seg2; - } - else - { - DEBUG_TypeDerefPointer(value, &testtype); - if( testtype != NULL || value->type == DEBUG_TypeIntConst ) - value->addr.off = DEBUG_GetExprValue(value, NULL); - } - } - else if (!value->addr.seg && !value->addr.off) - { - DEBUG_Printf(DBG_CHN_MESG,"Invalid expression\n"); - return; - } + return ret; } void @@ -486,11 +451,11 @@ DEBUG_Disassemble(const DBG_VALUE *xstart,const DBG_VALUE *xend,int offset) if (xstart) { start = *xstart; - _disassemble_fixaddr(&start); + DEBUG_GrabAddress(&start, TRUE); } if (xend) { end = *xend; - _disassemble_fixaddr(&end); + DEBUG_GrabAddress(&end, TRUE); } if (!xstart && !xend) { last = DEBUG_LastDisassemble; @@ -498,35 +463,20 @@ DEBUG_Disassemble(const DBG_VALUE *xstart,const DBG_VALUE *xend,int offset) DEBUG_GetCurrentAddress( &last ); for (i=0;i= MAX_TD_NESTING ) + if( ntypes >= allocated_types ) { - /* - * If this ever happens, just bump the counter. - */ - DEBUG_Printf(DBG_CHN_MESG, "Typedef nesting overflow\n"); - return FALSE; + allocated_types += 64; + curr_types = DBG_realloc(curr_types, sizeof(struct datatype*) * allocated_types); + if (!curr_types) return FALSE; } switch(c[1]) @@ -1087,6 +1084,9 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset, DEBUG_FreeRegisteredTypedefs(); DEBUG_FreeIncludes(); + DBG_free(curr_types); + curr_types = NULL; + allocated_types = 0; return TRUE; } diff --git a/debugger/winedbg.c b/debugger/winedbg.c index 46305748aa1..bcd75ed0696 100644 --- a/debugger/winedbg.c +++ b/debugger/winedbg.c @@ -338,12 +338,16 @@ static BOOL DEBUG_ExceptionProlog(BOOL is_debug, BOOL force, DWORD code) if (!is_debug || (DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_OVER) || (DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_INSTR)) { + + struct list_id list; + /* Show where we crashed */ curr_frame = 0; - DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, TRUE ); - DEBUG_Printf(DBG_CHN_MESG,": "); - DEBUG_Disasm( &addr, TRUE ); - DEBUG_Printf( DBG_CHN_MESG, "\n" ); + DEBUG_DisassembleInstruction(&addr); + + /* resets list internal arguments so we can look at source code when needed */ + DEBUG_FindNearestSymbol(&addr, TRUE, NULL, 0, &list); + if (list.sourcefile) DEBUG_List(&list, NULL, 0); } return TRUE; } -- 2.11.4.GIT