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:
parent
e22242df56
commit
71e0bdfcff
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user