Commit 71189b52 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

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
parent 78547774
...@@ -326,27 +326,9 @@ void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) ) ...@@ -326,27 +326,9 @@ void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) )
{ {
DBG_VALUE value = *_value; DBG_VALUE value = *_value;
int num; int num;
unsigned int seg2;
BYTE ch; BYTE ch;
assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST); if( !DEBUG_GrabAddress(&value, TRUE) ) return;
#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 ((num = DEBUG_FindBreakpoint(&value.addr, DBG_BREAK)) >= 1) if ((num = DEBUG_FindBreakpoint(&value.addr, DBG_BREAK)) >= 1)
{ {
...@@ -558,7 +540,7 @@ static int DEBUG_FindTriggeredWatchpoint(LPDWORD oldval) ...@@ -558,7 +540,7 @@ static int DEBUG_FindTriggeredWatchpoint(LPDWORD oldval)
int i; int i;
/* Method 1 => get triggered watchpoint from context (doesn't work on Linux /* 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++) for (i = 0; i < next_bp; i++)
{ {
...@@ -746,7 +728,7 @@ BOOL DEBUG_ShouldContinue( DWORD code, enum exec_mode mode, int * count ) ...@@ -746,7 +728,7 @@ BOOL DEBUG_ShouldContinue( DWORD code, enum exec_mode mode, int * count )
if (!DEBUG_ShallBreak(wpnum)) return TRUE; if (!DEBUG_ShallBreak(wpnum)) return TRUE;
#ifdef __i386__ #ifdef __i386__
addrlen = !addr.seg? 32 : DEBUG_GetSelectorType( addr.seg ); if (addr.seg) addrlen = DEBUG_GetSelectorType( addr.seg );
#endif #endif
DEBUG_Printf(DBG_CHN_MESG, "Stopped on watchpoint %d at ", wpnum); DEBUG_Printf(DBG_CHN_MESG, "Stopped on watchpoint %d at ", wpnum);
syminfo = DEBUG_PrintAddress( &addr, addrlen, TRUE ); syminfo = DEBUG_PrintAddress( &addr, addrlen, TRUE );
......
...@@ -53,14 +53,17 @@ typedef struct ...@@ -53,14 +53,17 @@ typedef struct
DWORD off; DWORD off;
} DBG_ADDR; } DBG_ADDR;
#define DV_TARGET 0xF00D
#define DV_HOST 0x50DA
#define DV_INVALID 0x0000
typedef struct typedef struct
{ {
struct datatype* type; struct datatype* type;
int cookie; /* DV_??? */ 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_ADDR addr;
} DBG_VALUE; } DBG_VALUE;
...@@ -353,6 +356,7 @@ extern void DEBUG_InvalAddr( const DBG_ADDR* addr ); ...@@ -353,6 +356,7 @@ extern void DEBUG_InvalAddr( const DBG_ADDR* addr );
extern void DEBUG_InvalLinAddr( void* addr ); extern void DEBUG_InvalLinAddr( void* addr );
extern DWORD DEBUG_ToLinear( const DBG_ADDR *address ); extern DWORD DEBUG_ToLinear( const DBG_ADDR *address );
extern void DEBUG_GetCurrentAddress( DBG_ADDR * ); extern void DEBUG_GetCurrentAddress( DBG_ADDR * );
extern BOOL DEBUG_GrabAddress( DBG_VALUE* value, BOOL fromCode );
#ifdef __i386__ #ifdef __i386__
extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def ); extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def );
extern BOOL DEBUG_FixSegment( DBG_ADDR* addr ); extern BOOL DEBUG_FixSegment( DBG_ADDR* addr );
...@@ -381,6 +385,15 @@ extern void DEBUG_InitCVDataTypes(void); ...@@ -381,6 +385,15 @@ extern void DEBUG_InitCVDataTypes(void);
extern void DEBUG_InfoRegisters(void); extern void DEBUG_InfoRegisters(void);
extern BOOL DEBUG_ValidateRegisters(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 */ /* debugger/stack.c */
extern void DEBUG_InfoStack(void); extern void DEBUG_InfoStack(void);
extern void DEBUG_BackTrace(BOOL noisy); extern void DEBUG_BackTrace(BOOL noisy);
...@@ -425,14 +438,6 @@ extern struct datatype * DEBUG_TypeCast(enum debug_type, const char *); ...@@ -425,14 +438,6 @@ extern struct datatype * DEBUG_TypeCast(enum debug_type, const char *);
extern int DEBUG_PrintTypeCast(const struct datatype *); extern int DEBUG_PrintTypeCast(const struct datatype *);
extern int DEBUG_PrintType( const DBG_VALUE* addr ); 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 */ /* debugger/winedbg.c */
#define DBG_CHN_MESG 1 #define DBG_CHN_MESG 1
#define DBG_CHN_ERR 2 #define DBG_CHN_ERR 2
......
...@@ -510,8 +510,9 @@ DBG_VALUE DEBUG_EvalExpr(struct expr * exp) ...@@ -510,8 +510,9 @@ DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
break; break;
case EXP_OP_SEG: case EXP_OP_SEG:
rtn.cookie = DV_TARGET; rtn.cookie = DV_TARGET;
rtn.type = NULL;
rtn.addr.seg = VAL(exp1); rtn.addr.seg = VAL(exp1);
exp->un.binop.result = VAL(exp2); rtn.addr.off = VAL(exp2);
#ifdef __i386__ #ifdef __i386__
DEBUG_FixSegment(&rtn.addr); DEBUG_FixSegment(&rtn.addr);
#endif #endif
......
...@@ -206,26 +206,18 @@ void DEBUG_WriteMemory( const DBG_VALUE* val, int value ) ...@@ -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; assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
int i;
unsigned char * pnt;
struct datatype * testtype;
assert(_value->cookie == DV_TARGET || _value->cookie == DV_HOST);
#ifdef __i386__ #ifdef __i386__
DEBUG_FixAddress( &value.addr, DEBUG_FixAddress( &value->addr,
(format == 'i') ? (fromCode) ? DEBUG_context.SegCs : DEBUG_context.SegDs);
DEBUG_context.SegCs :
DEBUG_context.SegDs );
#endif #endif
/* /*
...@@ -233,35 +225,44 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format ) ...@@ -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, * reading. We will use the same segment as what we have already,
* and hope that this is a sensible thing to do. * and hope that this is a sensible thing to do.
*/ */
if( value.type != NULL ) if (value->type != NULL) {
{ if (value->type == DEBUG_TypeIntConst) {
if( value.type == DEBUG_TypeIntConst )
{
/* /*
* We know that we have the actual offset stored somewhere * We know that we have the actual offset stored somewhere
* else in 32-bit space. Grab it, and we * else in 32-bit space. Grab it, and we
* should be all set. * should be all set.
*/ */
unsigned int seg2 = value.addr.seg; unsigned int seg2 = value->addr.seg;
value.addr.seg = 0; value->addr.seg = 0;
value.addr.off = DEBUG_GetExprValue(&value, NULL); value->addr.off = DEBUG_GetExprValue(value, NULL);
value.addr.seg = seg2; value->addr.seg = seg2;
} } else {
else struct datatype * testtype;
{
if (DEBUG_TypeDerefPointer(&value, &testtype) == 0) if (DEBUG_TypeDerefPointer(value, &testtype) == 0)
return; return FALSE;
if( testtype != NULL || value.type == DEBUG_TypeIntConst ) if (testtype != NULL || value->type == DEBUG_TypeIntConst)
{ value->addr.off = DEBUG_GetExprValue(value, NULL);
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;
else if (!value.addr.seg && !value.addr.off)
{
DEBUG_Printf(DBG_CHN_MESG,"Invalid expression\n");
return;
} }
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) if (format != 'i' && count > 1)
{ {
...@@ -301,13 +302,7 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format ) ...@@ -301,13 +302,7 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format )
return; return;
} }
case 'i': case 'i':
while (count--) while (count-- && DEBUG_DisassembleInstruction( &value.addr ));
{
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");
}
return; return;
#define DO_DUMP2(_t,_l,_f,_vv) { \ #define DO_DUMP2(_t,_l,_f,_vv) { \
_t _v; \ _t _v; \
......
...@@ -187,7 +187,7 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end) ...@@ -187,7 +187,7 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end)
/* /*
* Still couldn't find it. Ask user for path to add. * 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)); lstrcpynA(tmppath, readline(zbuf), sizeof(tmppath));
if( tmppath[strlen(tmppath)-1] == '\n' ) if( tmppath[strlen(tmppath)-1] == '\n' )
...@@ -425,56 +425,21 @@ DEBUG_List(struct list_id * source1, struct list_id * source2, ...@@ -425,56 +425,21 @@ DEBUG_List(struct list_id * source1, struct list_id * source2,
DBG_ADDR DEBUG_LastDisassemble={0,0}; DBG_ADDR DEBUG_LastDisassemble={0,0};
static int BOOL DEBUG_DisassembleInstruction(DBG_ADDR *addr)
_disassemble(DBG_ADDR *addr)
{ {
char ch; char ch;
BOOL ret = TRUE;
DEBUG_PrintAddress( addr, DEBUG_CurrThread->dbg_mode, TRUE );
DEBUG_Printf(DBG_CHN_MESG,": "); DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, TRUE);
if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(addr), &ch, sizeof(ch))) return 0; DEBUG_Printf(DBG_CHN_MESG, ": ");
DEBUG_Disasm( addr, TRUE ); 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"); DEBUG_Printf(DBG_CHN_MESG,"\n");
return 1; return ret;
}
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;
}
} }
void void
...@@ -486,11 +451,11 @@ DEBUG_Disassemble(const DBG_VALUE *xstart,const DBG_VALUE *xend,int offset) ...@@ -486,11 +451,11 @@ DEBUG_Disassemble(const DBG_VALUE *xstart,const DBG_VALUE *xend,int offset)
if (xstart) { if (xstart) {
start = *xstart; start = *xstart;
_disassemble_fixaddr(&start); DEBUG_GrabAddress(&start, TRUE);
} }
if (xend) { if (xend) {
end = *xend; end = *xend;
_disassemble_fixaddr(&end); DEBUG_GrabAddress(&end, TRUE);
} }
if (!xstart && !xend) { if (!xstart && !xend) {
last = DEBUG_LastDisassemble; last = DEBUG_LastDisassemble;
...@@ -498,35 +463,20 @@ DEBUG_Disassemble(const DBG_VALUE *xstart,const DBG_VALUE *xend,int offset) ...@@ -498,35 +463,20 @@ DEBUG_Disassemble(const DBG_VALUE *xstart,const DBG_VALUE *xend,int offset)
DEBUG_GetCurrentAddress( &last ); DEBUG_GetCurrentAddress( &last );
for (i=0;i<offset;i++) for (i=0;i<offset;i++)
if (!_disassemble(&last)) break; if (!DEBUG_DisassembleInstruction(&last)) break;
DEBUG_LastDisassemble = last; DEBUG_LastDisassemble = last;
return; return;
} }
last = start.addr; last = start.addr;
if (!xend) { if (!xend) {
for (i=0;i<offset;i++) for (i=0;i<offset;i++)
if (!_disassemble(&last)) break; if (!DEBUG_DisassembleInstruction(&last)) break;
DEBUG_LastDisassemble = last; DEBUG_LastDisassemble = last;
return; return;
} }
while (last.off <= end.addr.off) while (last.off <= end.addr.off)
if (!_disassemble(&last)) break; if (!DEBUG_DisassembleInstruction(&last)) break;
DEBUG_LastDisassemble = last; DEBUG_LastDisassemble = last;
return; return;
} }
#if 0
main(void)
{
int i, j;
DEBUG_AddPath("../../de");
while(1==1)
{
fscanf(stdin,"%d %d", &i, &j);
DEBUG_DisplaySource("dumpexe.c", i, j);
}
return 0;
}
#endif
...@@ -100,7 +100,9 @@ struct known_typedef ...@@ -100,7 +100,9 @@ struct known_typedef
#define NR_STAB_HASH 521 #define NR_STAB_HASH 521
struct known_typedef * ktd_head[NR_STAB_HASH] = {NULL,}; static struct known_typedef * ktd_head[NR_STAB_HASH] = {NULL,};
static struct datatype ** curr_types = NULL;
static int allocated_types = 0;
static unsigned int stab_hash( const char * name ) static unsigned int stab_hash( const char * name )
{ {
...@@ -236,8 +238,6 @@ DEBUG_FreeIncludes(void) ...@@ -236,8 +238,6 @@ DEBUG_FreeIncludes(void)
cu_nrofentries = 0; cu_nrofentries = 0;
} }
#define MAX_TD_NESTING 128
static static
struct datatype** struct datatype**
DEBUG_FileSubNr2StabEnum(int filenr, int subnr) DEBUG_FileSubNr2StabEnum(int filenr, int subnr)
...@@ -462,7 +462,6 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename) ...@@ -462,7 +462,6 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename)
char * c; char * c;
struct datatype * curr_type; struct datatype * curr_type;
struct datatype * datatype; struct datatype * datatype;
struct datatype * curr_types[MAX_TD_NESTING];
char element_name[1024]; char element_name[1024];
int ntypes = 0, ntp; int ntypes = 0, ntp;
int offset; int offset;
...@@ -476,7 +475,7 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename) ...@@ -476,7 +475,7 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename)
if( DEBUG_HandlePreviousTypedef(typename, ptr) ) if( DEBUG_HandlePreviousTypedef(typename, ptr) )
return TRUE; return TRUE;
/* /*
* Go from back to front. First we go through and figure out what * Go from back to front. First we go through and figure out what
* type numbers we need, and register those types. Then we go in * type numbers we need, and register those types. Then we go in
...@@ -490,13 +489,11 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename) ...@@ -490,13 +489,11 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename)
*/ */
struct datatype** dt = DEBUG_ReadTypeEnumBackwards(c-1); struct datatype** dt = DEBUG_ReadTypeEnumBackwards(c-1);
if( ntypes >= MAX_TD_NESTING ) if( ntypes >= allocated_types )
{ {
/* allocated_types += 64;
* If this ever happens, just bump the counter. curr_types = DBG_realloc(curr_types, sizeof(struct datatype*) * allocated_types);
*/ if (!curr_types) return FALSE;
DEBUG_Printf(DBG_CHN_MESG, "Typedef nesting overflow\n");
return FALSE;
} }
switch(c[1]) switch(c[1])
...@@ -1087,6 +1084,9 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset, ...@@ -1087,6 +1084,9 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
DEBUG_FreeRegisteredTypedefs(); DEBUG_FreeRegisteredTypedefs();
DEBUG_FreeIncludes(); DEBUG_FreeIncludes();
DBG_free(curr_types);
curr_types = NULL;
allocated_types = 0;
return TRUE; return TRUE;
} }
......
...@@ -338,12 +338,16 @@ static BOOL DEBUG_ExceptionProlog(BOOL is_debug, BOOL force, DWORD code) ...@@ -338,12 +338,16 @@ static BOOL DEBUG_ExceptionProlog(BOOL is_debug, BOOL force, DWORD code)
if (!is_debug || if (!is_debug ||
(DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_OVER) || (DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_OVER) ||
(DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_INSTR)) { (DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_INSTR)) {
struct list_id list;
/* Show where we crashed */ /* Show where we crashed */
curr_frame = 0; curr_frame = 0;
DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, TRUE ); DEBUG_DisassembleInstruction(&addr);
DEBUG_Printf(DBG_CHN_MESG,": ");
DEBUG_Disasm( &addr, TRUE ); /* resets list internal arguments so we can look at source code when needed */
DEBUG_Printf( DBG_CHN_MESG, "\n" ); DEBUG_FindNearestSymbol(&addr, TRUE, NULL, 0, &list);
if (list.sourcefile) DEBUG_List(&list, NULL, 0);
} }
return TRUE; return TRUE;
} }
......
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