diff options
| author | Logan Chien <tzuhsiang.chien@gmail.com> | 2015-05-29 15:33:38 +0000 |
|---|---|---|
| committer | Logan Chien <tzuhsiang.chien@gmail.com> | 2015-05-29 15:33:38 +0000 |
| commit | 7fab97f364d2e2f0beb7fffa3e42885db72982d5 (patch) | |
| tree | 87fa9f0023b1e0d4925d5435378528e150849a36 /libunwind/test | |
| parent | f4b4430f8c9c66c32a49e4c72bf594580d198501 (diff) | |
| download | bcm5719-llvm-7fab97f364d2e2f0beb7fffa3e42885db72982d5.tar.gz bcm5719-llvm-7fab97f364d2e2f0beb7fffa3e42885db72982d5.zip | |
libunwind: Fix unw_step() for ARM EHABI.
This commit fixes the unw_step() for ARM EHABI. However, this commit
also changes the implementation details for ARM EHABI.
The first change is that the personality function should call
__gnu_unwind_frame() for default (or de facto) frame unwinding based on
the ARM-defined unwind opcode. The function __gnu_unwind_frame() will
in turn calls unw_step() which actually unwinds the frame.
The second change is that the implementation _Unwind_Backtrace() should
no longer calls unw_step() to unwind the frame; since according to ARM
EHABI, the personality function should unwind the frame for us.
Special thanks to Anton for helpful suggestion on the initial version of
this patch.
llvm-svn: 238560
Diffstat (limited to 'libunwind/test')
| -rw-r--r-- | libunwind/test/libunwind_01.pass.cpp | 42 | ||||
| -rw-r--r-- | libunwind/test/libunwind_02.pass.cpp | 37 |
2 files changed, 79 insertions, 0 deletions
diff --git a/libunwind/test/libunwind_01.pass.cpp b/libunwind/test/libunwind_01.pass.cpp new file mode 100644 index 00000000000..6957d98f956 --- /dev/null +++ b/libunwind/test/libunwind_01.pass.cpp @@ -0,0 +1,42 @@ +#include <libunwind.h> +#include <stdlib.h> + +void backtrace(int lower_bound) { + unw_context_t context; + unw_getcontext(&context); + + unw_cursor_t cursor; + unw_init_local(&cursor, &context); + + int n = 0; + do { + ++n; + if (n > 100) { + abort(); + } + } while (unw_step(&cursor) > 0); + + if (n < lower_bound) { + abort(); + } +} + +void test1(int i) { + backtrace(i); +} + +void test2(int i, int j) { + backtrace(i); + test1(j); +} + +void test3(int i, int j, int k) { + backtrace(i); + test2(j, k); +} + +int main() { + test1(1); + test2(1, 2); + test3(1, 2, 3); +} diff --git a/libunwind/test/libunwind_02.pass.cpp b/libunwind/test/libunwind_02.pass.cpp new file mode 100644 index 00000000000..892c0873c56 --- /dev/null +++ b/libunwind/test/libunwind_02.pass.cpp @@ -0,0 +1,37 @@ +#include <assert.h> +#include <stdlib.h> +#include <unwind.h> + +#define EXPECTED_NUM_FRAMES 50 +#define NUM_FRAMES_UPPER_BOUND 100 + +_Unwind_Reason_Code callback(_Unwind_Context *context, void *cnt) { + int *i = (int *)cnt; + ++*i; + if (*i > NUM_FRAMES_UPPER_BOUND) { + abort(); + } + return _URC_NO_REASON; +} + +void test_backtrace() { + int n = 0; + _Unwind_Backtrace(&callback, &n); + if (n < EXPECTED_NUM_FRAMES) { + abort(); + } +} + +int test(int i) { + if (i == 0) { + test_backtrace(); + return 0; + } else { + return i + test(i - 1); + } +} + +int main() { + int total = test(50); + assert(total == 1275); +} |

