libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release


From: Lassi Tuura
Subject: Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?
Date: Tue, 22 Mar 2011 16:04:24 +0100

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 <address@hidden>
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;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]