[Top][All Lists]
[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;
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, (continued)
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Joe Damato, 2011/03/23
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Paul Pluzhnikov, 2011/03/23
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Arun Sharma, 2011/03/21
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Lassi Tuura, 2011/03/21
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Konstantin Belousov, 2011/03/21
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Arun Sharma, 2011/03/21
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Lassi Tuura, 2011/03/22
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?,
Lassi Tuura <=
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Arun Sharma, 2011/03/22
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Konstantin Belousov, 2011/03/22
- Re: [Libunwind-devel] Bug fixes in libunwind git = make another "release"?, Lassi Tuura, 2011/03/22