Hi, >> [mincore() vs. msync()] > > I'll add a configure time check for this unless someone else beats me to it.
How would you feel about the attached patch I am testing? It does switch to using msync() for us. Regards, Lassi commit f956f0c05d4e8a6b2d9c338e0031cd2402ddf70a Author: Lassi Tuura <[email protected]> Date: Tue Mar 22 11:30:21 2011 +0100 Auto-detect whether to use msync() or mincore() for address validation. diff --git a/configure.in b/configure.in index c0cdd9c..fe67da5 100644 --- a/configure.in +++ b/configure.in @@ -223,7 +223,8 @@ AC_ARG_ENABLE(conservative_checks, [ --enable-conservative-checks Validate all memory addresses before use], [enable_conservative_checks=$enableval], [enable_conservative_checks=yes]) if test x$enable_conservative_checks = xyes; then - CPPFLAGS="${CPPFLAGS} -DCONSERVATIVE_CHECKS" + AC_DEFINE(CONSERVATIVE_CHECKS, 1, + [Define to 1 if you want every memory access validated]) fi AC_MSG_RESULT([$enable_conservative_checks]) diff --git a/include/tdep-x86_64/libunwind_i.h b/include/tdep-x86_64/libunwind_i.h index ea502ec..fa5ebe9 100644 --- a/include/tdep-x86_64/libunwind_i.h +++ b/include/tdep-x86_64/libunwind_i.h @@ -155,6 +155,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) } #define tdep_needs_initialization UNW_OBJ(needs_initialization) +#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) #define tdep_init UNW_OBJ(init) /* Platforms that support UNW_INFO_FORMAT_TABLE need to define tdep_search_unwind_table. */ @@ -195,6 +196,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) extern int tdep_needs_initialization; extern void tdep_init (void); +extern void tdep_init_mem_validate (void); extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, unw_dyn_info_t *di, unw_proc_info_t *pi, int need_unwind_info, void *arg); diff --git a/src/x86_64/Gglobal.c b/src/x86_64/Gglobal.c index b24d779..8decf32 100644 --- a/src/x86_64/Gglobal.c +++ b/src/x86_64/Gglobal.c @@ -71,6 +71,8 @@ tdep_init (void) dwarf_init (); + tdep_init_mem_validate (); + #ifndef UNW_REMOTE_ONLY x86_64_local_addr_space_init (); #endif diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c index 8c69b84..ed816a2 100644 --- a/src/x86_64/Ginit.c +++ b/src/x86_64/Ginit.c @@ -81,6 +81,42 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, #define PAGE_SIZE 4096 #define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) +static int (*mem_validate_func) (void *addr, size_t len); +static int msync_validate (void *addr, size_t len) +{ + return msync (addr, len, MS_ASYNC); +} + +#ifdef HAVE_MINCORE +static int mincore_validate (void *addr, size_t len) +{ + unsigned char mvec[2]; /* Unaligned access may cross page boundary */ + return mincore (addr, len, mvec); +} +#endif + +/* Initialise memory validation method. On linux kernels <2.6.21, + mincore() returns incorrect value for MAP_PRIVATE mappings, + such as stacks. If mincore() was available at compile time, + check if we can actually use it. If not, use msync() instead. */ +PROTECTED void +tdep_init_mem_validate (void) +{ +#ifdef HAVE_MINCORE + unsigned char present; + if (mincore (&present, 1, &present) == 0) + { + Debug(1, "using mincore to validate memory\n"); + mem_validate_func = mincore_validate; + } + else +#endif + { + Debug(1, "using msync to validate memory\n"); + mem_validate_func = msync_validate; + } +} + /* Cache of already validated addresses */ #define NLGA 4 static unw_word_t last_good_addr[NLGA]; @@ -90,9 +126,6 @@ static int validate_mem (unw_word_t addr) { int i, victim; -#ifdef HAVE_MINCORE - unsigned char mvec[2]; /* Unaligned access may cross page boundary */ -#endif size_t len; if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) @@ -111,11 +144,7 @@ validate_mem (unw_word_t addr) return 0; } -#ifdef HAVE_MINCORE - if (mincore ((void *) addr, len, mvec) == -1) -#else - if (msync ((void *) addr, len, MS_ASYNC) == -1) -#endif + if (mem_validate_func ((void *) addr, len) == -1) return -1; victim = lga_victim; _______________________________________________ Libunwind-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/libunwind-devel
