support for stack traces under Linux x86_64, but the trace currently ends if working backward from JIT codes runs back into C-compiled code

svn: r12623
This commit is contained in:
Matthew Flatt 2008-11-27 16:14:31 +00:00
parent 8412e85b64
commit ca45e93763
5 changed files with 34 additions and 16 deletions

View File

@ -214,6 +214,7 @@
#if defined(__x86_64__)
# define MZ_USE_JIT_X86_64
# define MZ_JIT_USE_MPROTECT
# define MZ_USE_DWARF_LIBUNWIND
#endif
#if defined(powerpc)
# define MZ_USE_JIT_PPC

View File

@ -41,7 +41,7 @@
#include "schpriv.h"
#include "schmach.h"
#ifdef USE_DWARF_LIBUNWIND
#ifdef MZ_USE_DWARF_LIBUNWIND
# include "unwind/libunwind.h"
#endif
@ -8113,12 +8113,13 @@ Scheme_Object *scheme_native_stack_trace(void)
{
void *p, *q;
unsigned long stack_end, stack_start, halfway;
Get_Stack_Proc gs;
Scheme_Object *name, *last = NULL, *first = NULL, *tail;
int set_next_push = 0, prev_had_name = 0;
#ifdef USE_DWARF_LIBUNWIND
#ifdef MZ_USE_DWARF_LIBUNWIND
unw_context_t cx;
unw_cursor_t c;
#else
Get_Stack_Proc gs;
#endif
int use_unw = 0;
@ -8129,10 +8130,11 @@ Scheme_Object *scheme_native_stack_trace(void)
check_stack();
#endif
#ifdef USE_DWARF_LIBUNWIND
#ifdef MZ_USE_DWARF_LIBUNWIND
unw_getcontext(&cx);
unw_init_local(&c, &cx);
use_unw = 1;
p = NULL;
#else
gs = (Get_Stack_Proc)get_stack_pointer_code;
p = gs();
@ -8161,22 +8163,31 @@ Scheme_Object *scheme_native_stack_trace(void)
}
while (1) {
#ifdef USE_DWARF_LIBUNWIND
#ifdef MZ_USE_DWARF_LIBUNWIND
if (use_unw) {
p = unw_get_frame_pointer(&c);
q = unw_get_ip(&c);
q = (void *)unw_get_ip(&c);
} else {
q = NULL;
}
#endif
if (!use_unw) {
if (!(STK_COMP((unsigned long)p, stack_end)
&& STK_COMP(stack_start, (unsigned long)p)))
break;
&& STK_COMP(stack_start, (unsigned long)p)))
break;
q = ((void **)p)[RETURN_ADDRESS_OFFSET];
}
name = find_symbol((unsigned long)q);
#ifdef MZ_USE_DWARF_LIBUNWIND
if (name && use_unw) {
use_unw = 0;
p = (void *)unw_get_frame_pointer(&c);
if (!(STK_COMP((unsigned long)p, stack_end)
&& STK_COMP(stack_start, (unsigned long)p)))
break;
}
#endif
if (SCHEME_FALSEP(name) || SCHEME_VOIDP(name)) {
/* Code uses special calling convention */
#ifdef MZ_USE_JIT_PPC
@ -8250,16 +8261,16 @@ Scheme_Object *scheme_native_stack_trace(void)
prev_had_name = !!name;
#ifdef USE_DWARF_LIBUNWIND
#ifdef MZ_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;
use_unw = 0;
} else {
void *prev_q = q;
unw_step(&c);
q = unw_get_ip(&c);
q = (void *)unw_get_ip(&c);
if (q == prev_q)
break;
}

View File

@ -25,7 +25,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "../../sconfig.h"
#ifdef USE_DWARF_LIBUNWIND
#ifdef MZ_USE_DWARF_LIBUNWIND
#include <stddef.h>
#include "libunwind_i.h"
@ -2466,10 +2466,14 @@ int unw_step (unw_cursor_t *c)
int unwi_debug_level = 100;
#endif
unw_word_t unw_get_ip(unw_cursor_t *c)
{
return tdep_get_ip(((struct cursor *)c));
}
unw_word_t unw_get_frame_pointer(unw_cursor_t *c)
{
return ((struct cursor *)c)->dwarf.loc[6].val;
}
#endif

View File

@ -463,6 +463,7 @@ extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *);
extern int unw_is_signal_frame (unw_cursor_t *);
extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *);
extern unw_word_t unw_get_ip(unw_cursor_t *);
extern unw_word_t unw_get_frame_pointer(unw_cursor_t *);
extern const char *unw_strerror (int);
extern unw_addr_space_t unw_local_addr_space;

View File

@ -188,7 +188,7 @@ do { \
mem = NULL; \
} while (0)
#define UNW_DEBUG 1
#define UNW_DEBUG 0
#if UNW_DEBUG
#define unwi_debug_level UNWI_ARCH_OBJ(debug_level)
extern int unwi_debug_level;
@ -750,6 +750,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
#define tdep_get_as(c) ((c)->dwarf.as)
#define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
#define tdep_get_ip(c) ((c)->dwarf.ip)
#define tdep_get_cfa(c) ((c)->dwarf.cfa)
#define tdep_big_endian(as) 0
extern int tdep_needs_initialization;