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) )
{
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 );
......
......@@ -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
......
......@@ -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
......
......@@ -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; \
......
......@@ -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<offset;i++)
if (!_disassemble(&last)) break;
if (!DEBUG_DisassembleInstruction(&last)) break;
DEBUG_LastDisassemble = last;
return;
}
last = start.addr;
if (!xend) {
for (i=0;i<offset;i++)
if (!_disassemble(&last)) break;
if (!DEBUG_DisassembleInstruction(&last)) break;
DEBUG_LastDisassemble = last;
return;
}
while (last.off <= end.addr.off)
if (!_disassemble(&last)) break;
if (!DEBUG_DisassembleInstruction(&last)) break;
DEBUG_LastDisassemble = last;
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
#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 )
{
......@@ -236,8 +238,6 @@ DEBUG_FreeIncludes(void)
cu_nrofentries = 0;
}
#define MAX_TD_NESTING 128
static
struct datatype**
DEBUG_FileSubNr2StabEnum(int filenr, int subnr)
......@@ -462,7 +462,6 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename)
char * c;
struct datatype * curr_type;
struct datatype * datatype;
struct datatype * curr_types[MAX_TD_NESTING];
char element_name[1024];
int ntypes = 0, ntp;
int offset;
......@@ -476,7 +475,7 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename)
if( DEBUG_HandlePreviousTypedef(typename, ptr) )
return TRUE;
/*
* 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
......@@ -490,13 +489,11 @@ DEBUG_ParseTypedefStab(char * ptr, const char * typename)
*/
struct datatype** dt = DEBUG_ReadTypeEnumBackwards(c-1);
if( ntypes >= 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;
}
......
......@@ -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;
}
......
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