about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-04-07 23:26:18 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-04-07 23:26:18 +0530
commit751d6ede9db85f724b1e62306ea3de5221d8d92a (patch)
tree9ec6938458a588c7d66d0911f340baa037e077bf /src/libstd/sys
parentc58a9da8ba72224203f04c7cb1e80c7293699b28 (diff)
parent6e41885bd813a1628b6ca54058ab9595e9957c67 (diff)
downloadrust-751d6ede9db85f724b1e62306ea3de5221d8d92a.tar.gz
rust-751d6ede9db85f724b1e62306ea3de5221d8d92a.zip
Rollup merge of #32737 - timonvo:arm-ehabi-backtraces, r=alexcrichton
Fix backtraces on ARM EHABI.

Before this patch, our `rust_eh_personality_catch` routine would cut
backtracing short at the `__rust_try` function, due to it not handling
the `_US_FORCE_UNWIND` bit properly, which is passed by libunwind
implementations on ARM EHABI.

Examples of where the `_US_FORCE_UNWIND` bit is passed to the PR:
- GCC's libunwind: https://github.com/gcc-mirror/gcc/blob/f1717362de1e56fe1ffab540289d7d0c6ed48b20/libgcc/unwind-arm-common.inc#L590
- LLVM's libunwind: https://github.com/llvm-mirror/libunwind/blob/61278584b5c84c422ff5da10f46c3235c54636c9/src/UnwindLevel1-gcc-ext.c#L153
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/common/unwind/gcc.rs7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/libstd/sys/common/unwind/gcc.rs b/src/libstd/sys/common/unwind/gcc.rs
index ff6a11951dc..da7a340af35 100644
--- a/src/libstd/sys/common/unwind/gcc.rs
+++ b/src/libstd/sys/common/unwind/gcc.rs
@@ -224,8 +224,13 @@ pub mod eabi {
         context: *mut uw::_Unwind_Context
     ) -> uw::_Unwind_Reason_Code
     {
+        // Backtraces on ARM will call the personality routine with
+        // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
+        // we want to continue unwinding the stack, otherwise all our backtraces
+        // would end at __rust_try.
         if (state as c_int & uw::_US_ACTION_MASK as c_int)
-                           == uw::_US_VIRTUAL_UNWIND_FRAME as c_int { // search phase
+                           == uw::_US_VIRTUAL_UNWIND_FRAME as c_int
+               && (state as c_int & uw::_US_FORCE_UNWIND as c_int) == 0 { // search phase
             uw::_URC_HANDLER_FOUND // catch!
         }
         else { // cleanup phase