safer x86_64 backtrace

svn: r12630
This commit is contained in:
Matthew Flatt 2008-11-28 14:07:11 +00:00
parent 4ff0378fbf
commit 84ffa34efd
4 changed files with 48 additions and 8 deletions

View File

@ -8178,6 +8178,11 @@ Scheme_Object *scheme_native_stack_trace(void)
tail = scheme_null;
}
#ifdef MZ_USE_DWARF_LIBUNWIND
unw_set_safe_pointer_range(stack_start, stack_end);
unw_reset_bad_ptr_flag();
#endif
halfway = STK_DIFF(stack_end, (unsigned long)p) / 2;
if (halfway < CACHE_STACK_MIN_TRIGGER)
halfway = stack_end;
@ -8306,7 +8311,8 @@ Scheme_Object *scheme_native_stack_trace(void)
void *prev_q = q;
unw_step(&c);
q = (void *)unw_get_ip(&c);
if (q == prev_q)
if ((q == prev_q)
|| unw_reset_bad_ptr_flag())
break;
}
}

View File

@ -2462,6 +2462,35 @@ int unw_step (unw_cursor_t *c)
return dwarf_step(&((struct cursor *)c)->dwarf);
}
static int saw_bad_ptr = 0;
static char safe_space[8];
static unw_word_t safe_start_address, safe_end_address;
void unw_set_safe_pointer_range(unw_word_t s, unw_word_t e)
{
safe_start_address = s;
safe_end_address = e;
}
int unw_reset_bad_ptr_flag()
{
int v = saw_bad_ptr;
saw_bad_ptr = 0;
return v;
}
static void *safe_pointer(unw_word_t p)
{
if (safe_start_address != safe_end_address)
if ((p < safe_start_address)
|| (p >= safe_end_address)) {
saw_bad_ptr = 1;
return safe_space;
}
return (void *)p;
}
#if UNW_DEBUG
int unwi_debug_level = 100;
#endif
@ -2473,7 +2502,7 @@ unw_word_t unw_get_ip(unw_cursor_t *c)
unw_word_t unw_get_frame_pointer(unw_cursor_t *c)
{
return *(unw_word_t *)((struct cursor *)c)->dwarf.loc[6 /* = BP */].val;
return *(unw_word_t *)safe_pointer(((struct cursor *)c)->dwarf.loc[6 /* = BP */].val);
}
void unw_manual_step(unw_cursor_t *_c,
@ -2493,8 +2522,8 @@ void unw_manual_step(unw_cursor_t *_c,
c->dwarf.loc[13].val = (unw_word_t)r13_addr;
c->dwarf.loc[16].val = (unw_word_t)ip_addr;
c->dwarf.ip = *(unw_word_t *)ip_addr;
c->dwarf.cfa = *(unw_word_t *)sp_addr;
c->dwarf.ip = *(unw_word_t *)safe_pointer(ip_addr);
c->dwarf.cfa = *(unw_word_t *)safe_pointer(sp_addr);
c->dwarf.ret_addr_column = RIP;
c->dwarf.pi_valid = 0;
c->dwarf.hint = 0;

View File

@ -476,6 +476,9 @@ void unw_manual_step(unw_cursor_t *_c,
extern unw_addr_space_t unw_local_addr_space;
extern int unw_reset_bad_ptr_flag();
extern void unw_set_safe_pointer_range(unw_word_t s, unw_word_t e);
#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg)
extern int unw_tdep_is_fpreg (int);

View File

@ -695,12 +695,14 @@ struct cursor
# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
tdep_uc_addr((c)->as_arg, (r)), 0))
static void *safe_pointer(unw_word_t);
static inline int
dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
{
if (!DWARF_GET_LOC (loc))
return -1;
*val = *(unw_fpreg_t *) DWARF_GET_LOC (loc);
*val = *(unw_fpreg_t *) safe_pointer(DWARF_GET_LOC (loc));
return 0;
}
@ -709,7 +711,7 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
{
if (!DWARF_GET_LOC (loc))
return -1;
*(unw_fpreg_t *) DWARF_GET_LOC (loc) = val;
*(unw_fpreg_t *) safe_pointer(DWARF_GET_LOC (loc)) = val;
return 0;
}
@ -718,7 +720,7 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
{
if (!DWARF_GET_LOC (loc))
return -1;
*val = *(unw_word_t *) DWARF_GET_LOC (loc);
*val = *(unw_word_t *) safe_pointer(DWARF_GET_LOC (loc));
return 0;
}
@ -727,7 +729,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
{
if (!DWARF_GET_LOC (loc))
return -1;
*(unw_word_t *) DWARF_GET_LOC (loc) = val;
*(unw_word_t *) safe_pointer(DWARF_GET_LOC (loc)) = val;
return 0;
}