From 530238a12b4cb0eb132bf620670d513d31a52d4c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 7 Jan 2010 23:18:26 +0000 Subject: [PATCH] fix libunwind problem (seocnd attempt) svn: r17558 --- src/mzscheme/src/jit.c | 4 ++ src/mzscheme/src/unwind/libunwind.c | 68 ++++++++++++++++++++------- src/mzscheme/src/unwind/libunwind.h | 2 + src/mzscheme/src/unwind/libunwind_i.h | 1 + 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/mzscheme/src/jit.c b/src/mzscheme/src/jit.c index 7198a6d831..6ad4bbfc1a 100644 --- a/src/mzscheme/src/jit.c +++ b/src/mzscheme/src/jit.c @@ -12588,6 +12588,10 @@ Scheme_Object *scheme_native_stack_trace(void) } } +#ifdef MZ_USE_DWARF_LIBUNWIND + unw_destroy_local(&c); +#endif + if (last) SCHEME_CDR(last) = tail; else diff --git a/src/mzscheme/src/unwind/libunwind.c b/src/mzscheme/src/unwind/libunwind.c index 8c286d9ac0..11939cc907 100644 --- a/src/mzscheme/src/unwind/libunwind.c +++ b/src/mzscheme/src/unwind/libunwind.c @@ -30,6 +30,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include "libunwind_i.h" +/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ +/* region-based memory management */ +/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ + +static void *rgn_chain = NULL; + +static void *malloc_in_rgn(unw_addr_space_t as, long sz) +{ + void *p; + + /* 16 to ensure alignment, definitely >= sizeof(void*) */ + p = malloc(sz + 16); + + *(void **)p = as->mem_pool; + as->mem_pool = p; + + return (void *)((char *)p + 16); +} + +static void free_all_allocated(unw_addr_space_t as) +{ + while (as->mem_pool) { + void *next = *(void **)as->mem_pool; + free(as->mem_pool); + as->mem_pool = next; + } +} + /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ /* Gexpr.c */ /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ @@ -914,7 +942,7 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a, { pi->format = UNW_INFO_FORMAT_TABLE; pi->unwind_info_size = sizeof (dci); - pi->unwind_info = malloc (sizeof(struct dwarf_cie_info)); + pi->unwind_info = malloc_in_rgn (as, sizeof(struct dwarf_cie_info)); if (!pi->unwind_info) return UNW_ENOMEM; @@ -942,8 +970,8 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a, /* Gparser.c */ /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ -#define alloc_reg_state() (malloc (sizeof(dwarf_reg_state_t))) -#define free_reg_state(rs) (free (rs)) +#define alloc_reg_state(as) (malloc_in_rgn (as, sizeof(dwarf_reg_state_t))) +#define free_reg_state(rs) /* empty */ static inline int read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, @@ -1142,7 +1170,7 @@ run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, break; case DW_CFA_remember_state: - new_rs = alloc_reg_state (); + new_rs = alloc_reg_state (as); if (!new_rs) { Debug (1, "Out of memory in DW_CFA_remember_state\n"); @@ -1318,7 +1346,7 @@ put_unwind_info (struct dwarf_cursor *c, unw_proc_info_t *pi) if (pi->unwind_info); { - free (pi->unwind_info); + /* free (pi->unwind_info); */ pi->unwind_info = NULL; } } @@ -1806,6 +1834,7 @@ struct table_entry struct callback_data { /* in: */ + unw_addr_space_t as; unw_word_t ip; /* instruction-pointer we're looking for */ unw_proc_info_t *pi; /* proc-info pointer */ int need_unwind_info; @@ -1820,7 +1849,7 @@ linear_search (unw_addr_space_t as, unw_word_t ip, unw_word_t fde_count, unw_proc_info_t *pi, int need_unwind_info, void *arg) { - unw_accessors_t *a = unw_get_accessors (unw_local_addr_space); + unw_accessors_t *a = NULL; unw_word_t i = 0, fde_addr, addr = eh_frame_start; int ret; @@ -1954,17 +1983,17 @@ callback (struct dl_phdr_info *info, size_t size, void *ptr) return 0; } - a = unw_get_accessors (unw_local_addr_space); + a = unw_get_accessors (cb_data->as); addr = (unw_word_t) (hdr + 1); /* (Optionally) read eh_frame_ptr: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + if ((ret = dwarf_read_encoded_pointer (cb_data->as, a, &addr, hdr->eh_frame_ptr_enc, pi, &eh_frame_start, NULL)) < 0) return ret; /* (Optionally) read fde_count: */ - if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, + if ((ret = dwarf_read_encoded_pointer (cb_data->as, a, &addr, hdr->fde_count_enc, pi, &fde_count, NULL)) < 0) return ret; @@ -1988,7 +2017,7 @@ callback (struct dl_phdr_info *info, size_t size, void *ptr) abort (); cb_data->single_fde = 1; - return linear_search (unw_local_addr_space, ip, + return linear_search (cb_data->as, ip, eh_frame_start, eh_frame_end, fde_count, pi, need_unwind_info, NULL); } @@ -2025,6 +2054,7 @@ dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip, Debug (14, "looking for IP=0x%lx\n", (long) ip); + cb_data.as = as; cb_data.ip = ip; cb_data.pi = pi; cb_data.need_unwind_info = need_unwind_info; @@ -2119,7 +2149,6 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, /* glue */ /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ -unw_addr_space_t unw_local_addr_space; unw_accessors_t *unw_get_accessors (unw_addr_space_t unw_local_addr_space) { return NULL; @@ -2422,20 +2451,25 @@ common_init (struct cursor *c) int unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) { struct cursor *c = (struct cursor *) cursor; + unw_addr_space_t as; Debug (1, "(cursor=%p)\n", c); - if (!unw_local_addr_space) { - unw_local_addr_space = (unw_addr_space_t)malloc(sizeof(struct unw_addr_space)); - memset(unw_local_addr_space, 0, sizeof(unw_local_addr_space)); - /* unw_local_addr_space->caching_policy = UNW_CACHE_GLOBAL; */ - } + as = (unw_addr_space_t)malloc(sizeof(struct unw_addr_space)); + memset(as, 0, sizeof(struct unw_addr_space)); - c->dwarf.as = unw_local_addr_space; + c->dwarf.as = as; c->dwarf.as_arg = uc; return common_init (c); } +void unw_destroy_local(unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + free_all_allocated(c->dwarf.as); + free(c->dwarf.as); +} + int unw_step (unw_cursor_t *c) { return dwarf_step(&((struct cursor *)c)->dwarf); diff --git a/src/mzscheme/src/unwind/libunwind.h b/src/mzscheme/src/unwind/libunwind.h index 504b9b4b5b..85cefcd1b0 100644 --- a/src/mzscheme/src/unwind/libunwind.h +++ b/src/mzscheme/src/unwind/libunwind.h @@ -424,6 +424,7 @@ unw_save_loc_t; #define unw_destroy_addr_space UNW_OBJ(destroy_addr_space) #define unw_get_accessors UNW_ARCH_OBJ(get_accessors) #define unw_init_local UNW_OBJ(init_local) +#define unw_destroy_local UNW_OBJ(destroy_local) #define unw_init_remote UNW_OBJ(init_remote) #define unw_step UNW_OBJ(step) #define unw_resume UNW_OBJ(resume) @@ -449,6 +450,7 @@ extern int unw_set_caching_policy (unw_addr_space_t, unw_caching_policy_t); extern const char *unw_regname (unw_regnum_t); extern int unw_init_local (unw_cursor_t *, unw_context_t *); +extern void unw_destroy_local(unw_cursor_t *); extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *); extern int unw_step (unw_cursor_t *); extern int unw_resume (unw_cursor_t *); diff --git a/src/mzscheme/src/unwind/libunwind_i.h b/src/mzscheme/src/unwind/libunwind_i.h index e9c7926fa7..ac4525abbe 100644 --- a/src/mzscheme/src/unwind/libunwind_i.h +++ b/src/mzscheme/src/unwind/libunwind_i.h @@ -651,6 +651,7 @@ HIDDEN int dwarf_step (struct dwarf_cursor *c); struct unw_addr_space { + void *mem_pool; struct unw_accessors acc; unw_caching_policy_t caching_policy; #ifdef HAVE_ATOMIC_OPS_H