Commit 2ce9ad86 authored by Ove Kaaven's avatar Ove Kaaven Committed by Alexandre Julliard

Tidyed up stack backtrace code a bit, and added a simple special

case for backtracing from a null EIP.
parent 66791afa
...@@ -79,7 +79,7 @@ void DEBUG_InfoStack(void) ...@@ -79,7 +79,7 @@ void DEBUG_InfoStack(void)
} }
#ifdef __i386__ #ifdef __i386__
static void DEBUG_ForceFrame(DBG_ADDR *stack, DBG_ADDR *code, int frameno, int bits, int noisy) static void DEBUG_ForceFrame(DBG_ADDR *stack, DBG_ADDR *code, int frameno, int bits, int noisy, const char *caveat)
{ {
int theframe = nframe++; int theframe = nframe++;
frames = (struct bt_info *)DBG_realloc(frames, frames = (struct bt_info *)DBG_realloc(frames,
...@@ -99,16 +99,16 @@ static void DEBUG_ForceFrame(DBG_ADDR *stack, DBG_ADDR *code, int frameno, int b ...@@ -99,16 +99,16 @@ static void DEBUG_ForceFrame(DBG_ADDR *stack, DBG_ADDR *code, int frameno, int b
frames[theframe].ss = stack->seg; frames[theframe].ss = stack->seg;
frames[theframe].ebp = stack->off; frames[theframe].ebp = stack->off;
if (noisy) { if (noisy) {
DEBUG_Printf( DBG_CHN_MESG, (bits == 16) ? " (bp=%04lx)\n" : " (ebp=%08lx)\n", stack->off ); DEBUG_Printf( DBG_CHN_MESG, (bits == 16) ? " (bp=%04lx%s)\n" : " (ebp=%08lx%s)\n", stack->off, caveat?caveat:"" );
} }
} }
static BOOL DEBUG_Frame16(DBG_ADDR *addr, unsigned int *cs, int frameno, int noisy) static BOOL DEBUG_Frame16(DBG_ADDR *addr, unsigned int *cs, int frameno, int noisy)
{ {
unsigned int ss = addr->seg, possible_cs = 0; unsigned int possible_cs = 0;
FRAME16 frame; FRAME16 frame;
int theframe = nframe;
void* p = (void*)DEBUG_ToLinear(addr); void* p = (void*)DEBUG_ToLinear(addr);
DBG_ADDR code;
if (!p) return FALSE; if (!p) return FALSE;
...@@ -117,12 +117,7 @@ static BOOL DEBUG_Frame16(DBG_ADDR *addr, unsigned int *cs, int frameno, int noi ...@@ -117,12 +117,7 @@ static BOOL DEBUG_Frame16(DBG_ADDR *addr, unsigned int *cs, int frameno, int noi
return FALSE; return FALSE;
} }
if (!frame.bp) return FALSE; if (!frame.bp) return FALSE;
nframe++;
frames = (struct bt_info *)DBG_realloc(frames,
nframe*sizeof(struct bt_info));
if (noisy)
DEBUG_Printf(DBG_CHN_MESG,"%s%d ", (theframe == curr_frame ? "=>" : " "),
frameno);
if (frame.bp & 1) *cs = frame.cs; if (frame.bp & 1) *cs = frame.cs;
else { else {
/* not explicitly marked as far call, /* not explicitly marked as far call,
...@@ -138,33 +133,19 @@ static BOOL DEBUG_Frame16(DBG_ADDR *addr, unsigned int *cs, int frameno, int noi ...@@ -138,33 +133,19 @@ static BOOL DEBUG_Frame16(DBG_ADDR *addr, unsigned int *cs, int frameno, int noi
} }
} }
} }
frames[theframe].cs = addr->seg = *cs; code.seg = *cs;
frames[theframe].eip = addr->off = frame.ip; code.off = frame.ip;
if (noisy) addr->off = frame.bp & ~1;
frames[theframe].frame = DEBUG_PrintAddressAndArgs( addr, 16, DEBUG_ForceFrame(addr, &code, frameno, 16, noisy, possible_cs ? ", far call assumed" : NULL );
frame.bp, TRUE );
else
DEBUG_FindNearestSymbol( addr, TRUE,
&frames[theframe].frame.sym, frame.bp,
&frames[theframe].frame.list);
frames[theframe].ss = addr->seg = ss;
frames[theframe].ebp = addr->off = frame.bp & ~1;
if (noisy) {
DEBUG_Printf( DBG_CHN_MESG, " (bp=%04lx", addr->off );
if (possible_cs) {
DEBUG_Printf( DBG_CHN_MESG, ", far call assumed" );
}
DEBUG_Printf( DBG_CHN_MESG, ")\n" );
}
return TRUE; return TRUE;
} }
static BOOL DEBUG_Frame32(DBG_ADDR *addr, unsigned int *cs, int frameno, int noisy) static BOOL DEBUG_Frame32(DBG_ADDR *addr, unsigned int *cs, int frameno, int noisy)
{ {
unsigned int ss = addr->seg;
FRAME32 frame; FRAME32 frame;
int theframe = nframe;
void* p = (void*)DEBUG_ToLinear(addr); void* p = (void*)DEBUG_ToLinear(addr);
DBG_ADDR code;
DWORD old_bp = addr->off;
if (!p) return FALSE; if (!p) return FALSE;
...@@ -173,27 +154,12 @@ static BOOL DEBUG_Frame32(DBG_ADDR *addr, unsigned int *cs, int frameno, int noi ...@@ -173,27 +154,12 @@ static BOOL DEBUG_Frame32(DBG_ADDR *addr, unsigned int *cs, int frameno, int noi
return FALSE; return FALSE;
} }
if (!frame.ip) return FALSE; if (!frame.ip) return FALSE;
nframe++; code.seg = *cs;
frames = (struct bt_info *)DBG_realloc(frames, code.off = frame.ip;
nframe*sizeof(struct bt_info));
if (noisy)
DEBUG_Printf(DBG_CHN_MESG,"%s%d ", (theframe == curr_frame ? "=>" : " "),
frameno);
frames[theframe].cs = addr->seg = *cs;
frames[theframe].eip = addr->off = frame.ip;
if (noisy)
frames[theframe].frame = DEBUG_PrintAddressAndArgs( addr, 32,
frame.bp, TRUE );
else
DEBUG_FindNearestSymbol( addr, TRUE,
&frames[theframe].frame.sym, frame.bp,
&frames[theframe].frame.list);
if (noisy) DEBUG_Printf( DBG_CHN_MESG, " (ebp=%08lx)\n", frame.bp );
frames[theframe].ss = addr->seg = ss;
frames[theframe].ebp = frame.bp;
if (addr->off == frame.bp) return FALSE;
addr->off = frame.bp; addr->off = frame.bp;
DEBUG_ForceFrame(addr, &code, frameno, 32, noisy, NULL);
if (addr->off == old_bp) return FALSE;
return TRUE; return TRUE;
} }
#endif #endif
...@@ -218,11 +184,10 @@ void DEBUG_BackTrace(BOOL noisy) ...@@ -218,11 +184,10 @@ void DEBUG_BackTrace(BOOL noisy)
if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Backtrace:\n" ); if (noisy) DEBUG_Printf( DBG_CHN_MESG, "Backtrace:\n" );
nframe = 1; nframe = 0;
if (frames) DBG_free( frames ); if (frames) DBG_free( frames );
frames = (struct bt_info *) DBG_alloc( sizeof(struct bt_info) ); /* frames = (struct bt_info *) DBG_alloc( sizeof(struct bt_info) ); */
if (noisy) frames = NULL;
DEBUG_Printf(DBG_CHN_MESG,"%s%d ",(curr_frame == 0 ? "=>" : " "), frameno);
if (DEBUG_IsSelectorSystem(ss)) ss = 0; if (DEBUG_IsSelectorSystem(ss)) ss = 0;
if (DEBUG_IsSelectorSystem(cs)) cs = 0; if (DEBUG_IsSelectorSystem(cs)) cs = 0;
...@@ -231,29 +196,29 @@ void DEBUG_BackTrace(BOOL noisy) ...@@ -231,29 +196,29 @@ void DEBUG_BackTrace(BOOL noisy)
switch (DEBUG_GetSelectorType(ss)) switch (DEBUG_GetSelectorType(ss))
{ {
case 32: case 32:
frames[0].cs = addr.seg = cs; code.seg = cs;
frames[0].eip = addr.off = DEBUG_context.Eip; code.off = DEBUG_context.Eip;
if (noisy) addr.seg = ss;
frames[0].frame = DEBUG_PrintAddress( &addr, 32, TRUE ); addr.off = DEBUG_context.Ebp;
else DEBUG_ForceFrame( &addr, &code, frameno, 32, noisy, NULL );
DEBUG_FindNearestSymbol( &addr, TRUE, &frames[0].frame.sym, 0, if (!(code.seg || code.off)) {
&frames[0].frame.list); /* trying to execute a null pointer... yuck...
frames[0].ss = addr.seg = ss; * if it was a call to null, the return EIP should be
frames[0].ebp = addr.off = DEBUG_context.Ebp; * available at SS:ESP, so let's try to retrieve it */
if (noisy) DEBUG_Printf( DBG_CHN_MESG, " (ebp=%08x)\n", frames[0].ebp ); tmp.seg = ss;
tmp.off = DEBUG_context.Esp;
if (DEBUG_READ_MEM(DEBUG_ToLinear(&tmp), &code.off, sizeof(code.off))) {
DEBUG_ForceFrame( &addr, &code, ++frameno, 32, noisy, ", null call assumed" );
}
}
is16 = FALSE; is16 = FALSE;
break; break;
case 16: case 16:
frames[0].cs = addr.seg = cs; code.seg = cs;
frames[0].eip = addr.off = LOWORD(DEBUG_context.Eip); code.off = LOWORD(DEBUG_context.Eip);
if (noisy) addr.seg = ss;
frames[0].frame = DEBUG_PrintAddress( &addr, 16, TRUE ); addr.off = LOWORD(DEBUG_context.Ebp);
else DEBUG_ForceFrame( &addr, &code, frameno, 16, noisy, NULL );
DEBUG_FindNearestSymbol( &addr, TRUE, &frames[0].frame.sym, 0,
&frames[0].frame.list);
frames[0].ss = addr.seg = ss;
frames[0].ebp = addr.off = LOWORD(DEBUG_context.Ebp);
if (noisy) DEBUG_Printf( DBG_CHN_MESG, " (bp=%04x)\n", frames[0].ebp );
is16 = TRUE; is16 = TRUE;
break; break;
default: default:
...@@ -317,7 +282,7 @@ void DEBUG_BackTrace(BOOL noisy) ...@@ -317,7 +282,7 @@ void DEBUG_BackTrace(BOOL noisy)
cs = 0; cs = 0;
addr.seg = 0; addr.seg = 0;
addr.off = frame32.ebp; addr.off = frame32.ebp;
DEBUG_ForceFrame( &addr, &code, ++frameno, 32, noisy ); DEBUG_ForceFrame( &addr, &code, ++frameno, 32, noisy, NULL );
next_switch = cur_switch; next_switch = cur_switch;
tmp.seg = SELECTOROF(next_switch); tmp.seg = SELECTOROF(next_switch);
...@@ -351,7 +316,7 @@ void DEBUG_BackTrace(BOOL noisy) ...@@ -351,7 +316,7 @@ void DEBUG_BackTrace(BOOL noisy)
cs = frame16.cs; cs = frame16.cs;
addr.seg = SELECTOROF(next_switch); addr.seg = SELECTOROF(next_switch);
addr.off = frame16.bp; addr.off = frame16.bp;
DEBUG_ForceFrame( &addr, &code, ++frameno, 16, noisy ); DEBUG_ForceFrame( &addr, &code, ++frameno, 16, noisy, NULL );
next_switch = cur_switch; next_switch = cur_switch;
if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) { if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) {
......
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