summaryrefslogtreecommitdiff
path: root/src/x86_64/Gstep.c
diff options
context:
space:
mode:
authorArun Sharma <arun.sharma@google.com>2008-06-16 14:35:53 -0600
committerDavid Mosberger-Tang <davidm@koala.mostang.com>2008-06-16 14:35:53 -0600
commit649f1fb3449a65dd0626a709432d8b02a7c56bbc (patch)
tree61b412e9938a8ebfa870a4cf202e1697cff22383 /src/x86_64/Gstep.c
parent183d28a0668f100a181cc665ea702985d2ee717e (diff)
downloadlibunwind-649f1fb3449a65dd0626a709432d8b02a7c56bbc.tar.gz
[X86-64] For local unwinding, we have a defence mechanism against
bad/missing unwind information, which could result in libunwind dereferencing bad pointers. This mechanism is based on msync(2) system call and significantly reduces the chances of a bad pointer dereference in libunwind. The original idea was to turn this mechanism on only when necessary i.e. libunwind didn't find proper unwind information for a IP. There are a couple of problems in the current implementation. * The flag is global and is modified without locking * The flag isn't reset when starting a new unwind The attached patch makes ->validate a per-thread setting by moving it into struct cursor from unw_local_addr_space and resets it to false when starting a new unwind. As a result, cursor->as_arg points to the cursor itself instead of the ucontext (for the local case). This was found to reduce the number of msync() system calls from an application using libunwind significantly. Signed-off-by: Paul Pluzhnikov <ppluzhnikov@google.com> Signed-off-by: Arun Sharma <arun.sharma@google.com>
Diffstat (limited to 'src/x86_64/Gstep.c')
-rw-r--r--src/x86_64/Gstep.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/x86_64/Gstep.c b/src/x86_64/Gstep.c
index 75f796f5..2da1c25d 100644
--- a/src/x86_64/Gstep.c
+++ b/src/x86_64/Gstep.c
@@ -71,6 +71,10 @@ unw_step (unw_cursor_t *cursor)
unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa;
struct dwarf_loc rbp_loc, rsp_loc, rip_loc;
+ /* We could get here because of missing/bad unwind information.
+ Validate all addresses before dereferencing. */
+ c->validate = 1;
+
Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
if (unw_is_signal_frame (cursor))