libunwind-devel
[Top][All Lists]
Advanced

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

[Libunwind-devel] patch to break out of loop when dwarf_step and is_sign


From: dave lerner
Subject: [Libunwind-devel] patch to break out of loop when dwarf_step and is_signal_frame fail on x86
Date: Thu, 7 Mar 2013 12:25:19 -0600

Thanks to all the developers for the work on this well designed, implemented, 
and usefull package.  

I have an issue and proposed fixed attached below with the x86 frame based 
signal unwinder.  Hans Boehm seems like a likely reviewer.

Sorry in advance if the format is not correct.
Dave Lerner
-----------------------------------------------------------------

Break out of loop when dwarf_step and is_signal_frame fail on x86

On an x86 target, unw_step returns 1, 'success', even though the
dwarf_step, unw_is_signal_frame and unw_handle_signal_frame each
fail.  The cursor is not updated, so that unw_step callers never
exit their loop.  This was observed for x86 when the libunwind api
was called from a function with the dll __attribute__((constructor))
tag.

In this case, in unw_step, a bad cfa address causes dwarf_step
to fail. Unw_step calls unw_is_signal_frame which calls access_mem
which also fails probing the bad address.  That function's negative
valued return, is returned by unw_is_signal_frame. But the non-0 return,
drops unw_step into the block to call causes unw_handle_signal_frame to
handle the frame and adjust the cursor. The bad address causes
unw_handle_signal_frame to also fail, but that function returns 0 on
failure.  Unw_step handles the 0 from unw_handle_signal_frame by
returning 1, 'success' to the caller although the cursor was not
updated by the the signal frame handler.

The patch addresses the problem of a very bad address by changing
unw_step to return the negative return value when unw_is_signal_frame
returns that error value. 
Signed-off-by: Dave Lerner <address@hidden>

diff --git a/src/x86/Gos-linux.c b/src/x86/Gos-linux.c
index 31f83ba..0bc390c 100644
--- a/src/x86/Gos-linux.c
+++ b/src/x86/Gos-linux.c
@@ -57,10 +57,11 @@ unw_is_signal_frame (unw_cursor_t *cursor)
      if SA_SIGINFO is specified.
   */
   ip = c->dwarf.ip;
-  if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
-      || (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0)
-    return ret;
-  ret = ((w0 == 0x0077b858 && w1 == 0x80cd0000)
+  if ( (*a->access_mem) (as, ip, &w0, 0, arg) < 0
+      || (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0)
+    ret = 0;
+  else 
+    ret = ((w0 == 0x0077b858 && w1 == 0x80cd0000)
         || (w0 == 0x0000adb8 && (w1 & 0xffffff) == 0x80cd00));
   Debug (16, "returning %d\n", ret);
   return ret;



reply via email to

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