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 <[email protected]> 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; _______________________________________________ Libunwind-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/libunwind-devel
