more repairs to stack trace and caching

Fixes problems with d15fda9d6b, but also fixes a problem that
could show up in non-libunwind mode and cause lost frames.
This commit is contained in:
Matthew Flatt 2014-12-15 10:41:17 -07:00
parent e22242df56
commit 71e0bdfcff
2 changed files with 30 additions and 15 deletions

View File

@ -877,6 +877,8 @@ static int common2(mz_jit_state *jitter, void *_data)
jit_jmpr(JIT_R2); jit_jmpr(JIT_R2);
CHECK_LIMIT(); CHECK_LIMIT();
scheme_jit_register_sub_func(jitter, sjc.stack_cache_pop_code, scheme_false);
/* *** bad_app_vals_target *** */ /* *** bad_app_vals_target *** */
/* Non-proc is in R0 */ /* Non-proc is in R0 */
sjc.bad_app_vals_target = jit_get_ip(); sjc.bad_app_vals_target = jit_get_ip();

View File

@ -161,10 +161,10 @@ static void set_cache(void *p, Scheme_Object *last)
Scheme_Object *scheme_native_stack_trace(void) Scheme_Object *scheme_native_stack_trace(void)
{ {
void *p, *q, *prev_frame_p; void *p, *q, *cache_frame_p;
uintptr_t stack_end, real_stack_end, stack_start, halfway; uintptr_t stack_end, real_stack_end, stack_start, halfway;
Scheme_Object *name, *last = NULL, *first = NULL, *tail; Scheme_Object *name, *last = NULL, *first = NULL, *tail;
int prev_had_name = 0; int cache_had_name = 0;
#ifdef MZ_USE_DWARF_LIBUNWIND #ifdef MZ_USE_DWARF_LIBUNWIND
unw_context_t cx; unw_context_t cx;
unw_cursor_t c; unw_cursor_t c;
@ -318,15 +318,14 @@ Scheme_Object *scheme_native_stack_trace(void)
} }
#endif #endif
prev_frame_p = NULL; cache_frame_p = NULL;
while (unsuccess < UNKNOWN_FRAME_LIMIT) { while (unsuccess < UNKNOWN_FRAME_LIMIT) {
#ifdef MZ_USE_DWARF_LIBUNWIND #ifdef MZ_USE_DWARF_LIBUNWIND
if (use_unw) { if (use_unw)
q = (void *)unw_get_ip(&c); q = (void *)unw_get_ip(&c);
} else { else
q = NULL; q = NULL;
}
#endif #endif
if (!use_unw) { if (!use_unw) {
@ -407,6 +406,21 @@ Scheme_Object *scheme_native_stack_trace(void)
name = NULL; name = NULL;
} }
#ifdef MZ_USE_DWARF_LIBUNWIND
if (use_unw) {
if (manual_unw) {
cache_frame_p = (void **)unw_get_frame_pointer(&c);
if (!(STK_COMP((uintptr_t)cache_frame_p, stack_end)
&& STK_COMP(stack_start, (uintptr_t)cache_frame_p)))
break;
cache_had_name = name && (last || !SCHEME_NULLP(name));
} else {
cache_frame_p = NULL;
cache_had_name = 0;
}
}
#endif
if (name && !SCHEME_NULLP(name)) { /* null is used to help unwind without a true name */ if (name && !SCHEME_NULLP(name)) { /* null is used to help unwind without a true name */
name = scheme_make_pair(name, scheme_null); name = scheme_make_pair(name, scheme_null);
if (last) if (last)
@ -433,16 +447,17 @@ Scheme_Object *scheme_native_stack_trace(void)
might not be used (depending on how the C compiler optimized the might not be used (depending on how the C compiler optimized the
code); any frame whose procedure has a name is JITted code, so code); any frame whose procedure has a name is JITted code, so
it will use the return address from the stack. */ it will use the return address from the stack. */
if (STK_COMP((uintptr_t)halfway, (uintptr_t)prev_frame_p) if (STK_COMP((uintptr_t)halfway, (uintptr_t)cache_frame_p)
&& prev_had_name) { && cache_had_name) {
set_cache(prev_frame_p, last); set_cache(cache_frame_p, last);
if (!added_list_elem) if (!added_list_elem)
shift_cache_to_next = 1; shift_cache_to_next = 1;
halfway = stack_end; halfway = stack_end;
unsuccess = -100000; /* if we got halfway, no need to bail out later */ unsuccess = -8 * UNKNOWN_FRAME_LIMIT; /* if we got halfway, less likely to bail out later */
} }
prev_had_name = !!name; if (!use_unw)
cache_had_name = !!name;
#ifdef MZ_USE_DWARF_LIBUNWIND #ifdef MZ_USE_DWARF_LIBUNWIND
if (use_unw) { if (use_unw) {
@ -453,7 +468,6 @@ Scheme_Object *scheme_native_stack_trace(void)
if (!(STK_COMP((uintptr_t)pp, stack_end) if (!(STK_COMP((uintptr_t)pp, stack_end)
&& STK_COMP(stack_start, (uintptr_t)pp))) && STK_COMP(stack_start, (uintptr_t)pp)))
break; break;
prev_frame_p = pp;
# ifdef MZ_USE_JIT_ARM # ifdef MZ_USE_JIT_ARM
stack_addr = (unw_word_t)&(pp[JIT_NEXT_FP_OFFSET+2]); stack_addr = (unw_word_t)&(pp[JIT_NEXT_FP_OFFSET+2]);
unw_manual_step(&c, unw_manual_step(&c,
@ -468,7 +482,6 @@ Scheme_Object *scheme_native_stack_trace(void)
# endif # endif
manual_unw = 0; manual_unw = 0;
} else { } else {
prev_frame_p = NULL;
unw_step(&c); unw_step(&c);
q = (void *)unw_get_ip(&c); q = (void *)unw_get_ip(&c);
if (unw_reset_bad_ptr_flag(&c)) if (unw_reset_bad_ptr_flag(&c))
@ -482,12 +495,12 @@ Scheme_Object *scheme_native_stack_trace(void)
if (STK_COMP((uintptr_t)q, (uintptr_t)p)) if (STK_COMP((uintptr_t)q, (uintptr_t)p))
break; break;
p = q; p = q;
prev_frame_p = p; cache_frame_p = p;
} }
} }
if (shift_cache_to_next) if (shift_cache_to_next)
stack_cache_stack[stack_cache_stack_pos].cache = scheme_null; stack_cache_stack[stack_cache_stack_pos].cache = tail;
#ifdef MZ_USE_DWARF_LIBUNWIND #ifdef MZ_USE_DWARF_LIBUNWIND
unw_destroy_local(&c); unw_destroy_local(&c);