last bit of prep for x86_64 backtrace (might even work)

svn: r12622
This commit is contained in:
Matthew Flatt 2008-11-27 15:24:47 +00:00
parent 84f52ab704
commit 8412e85b64

View File

@ -41,6 +41,9 @@
#include "schpriv.h" #include "schpriv.h"
#include "schmach.h" #include "schmach.h"
#ifdef USE_DWARF_LIBUNWIND
# include "unwind/libunwind.h"
#endif
#ifdef MZ_USE_JIT #ifdef MZ_USE_JIT
@ -8113,6 +8116,11 @@ Scheme_Object *scheme_native_stack_trace(void)
Get_Stack_Proc gs; Get_Stack_Proc gs;
Scheme_Object *name, *last = NULL, *first = NULL, *tail; Scheme_Object *name, *last = NULL, *first = NULL, *tail;
int set_next_push = 0, prev_had_name = 0; int set_next_push = 0, prev_had_name = 0;
#ifdef USE_DWARF_LIBUNWIND
unw_context_t cx;
unw_cursor_t c;
#endif
int use_unw = 0;
if (!get_stack_pointer_code) if (!get_stack_pointer_code)
return NULL; return NULL;
@ -8121,8 +8129,15 @@ Scheme_Object *scheme_native_stack_trace(void)
check_stack(); check_stack();
#endif #endif
#ifdef USE_DWARF_LIBUNWIND
unw_getcontext(&cx);
unw_init_local(&c, &cx);
use_unw = 1;
#else
gs = (Get_Stack_Proc)get_stack_pointer_code; gs = (Get_Stack_Proc)get_stack_pointer_code;
p = gs(); p = gs();
#endif
stack_start = scheme_approx_sp(); stack_start = scheme_approx_sp();
if (stack_cache_stack_pos) { if (stack_cache_stack_pos) {
@ -8145,9 +8160,21 @@ Scheme_Object *scheme_native_stack_trace(void)
#endif #endif
} }
while (STK_COMP((unsigned long)p, stack_end) while (1) {
&& STK_COMP(stack_start, (unsigned long)p)) { #ifdef USE_DWARF_LIBUNWIND
if (use_unw) {
p = unw_get_frame_pointer(&c);
q = unw_get_ip(&c);
}
#endif
if (!use_unw) {
if (!(STK_COMP((unsigned long)p, stack_end)
&& STK_COMP(stack_start, (unsigned long)p)))
break;
q = ((void **)p)[RETURN_ADDRESS_OFFSET]; q = ((void **)p)[RETURN_ADDRESS_OFFSET];
}
name = find_symbol((unsigned long)q); name = find_symbol((unsigned long)q);
if (SCHEME_FALSEP(name) || SCHEME_VOIDP(name)) { if (SCHEME_FALSEP(name) || SCHEME_VOIDP(name)) {
@ -8223,11 +8250,29 @@ Scheme_Object *scheme_native_stack_trace(void)
prev_had_name = !!name; prev_had_name = !!name;
#ifdef USE_DWARF_LIBUNWIND
if (use_unw) {
if (name) {
/* A JIT-generated function, so we unwind ourselves... */
/* For now, once we cross into JIT world, stay there. */
use_uwn = 0;
} else {
void *prev_q = q;
unw_step(&c);
q = unw_get_ip(&c);
if (q == prev_q)
break;
}
}
#endif
if (!use_unw) {
q = *(void **)p; q = *(void **)p;
if (STK_COMP((unsigned long)q, (unsigned long)p)) if (STK_COMP((unsigned long)q, (unsigned long)p))
break; break;
p = q; p = q;
} }
}
if (last) if (last)
SCHEME_CDR(last) = tail; SCHEME_CDR(last) = tail;
@ -8257,8 +8302,6 @@ void scheme_dump_stack_trace(void)
while (STK_COMP((unsigned long)p, stack_end) while (STK_COMP((unsigned long)p, stack_end)
&& STK_COMP(stack_start, (unsigned long)p)) { && STK_COMP(stack_start, (unsigned long)p)) {
q = ((void **)p)[RETURN_ADDRESS_OFFSET];
name = find_symbol((unsigned long)q); name = find_symbol((unsigned long)q);
if (SCHEME_FALSEP(name)) { if (SCHEME_FALSEP(name)) {
/* Code uses special calling convention */ /* Code uses special calling convention */