summaryrefslogtreecommitdiffstats
path: root/libunwind/test
diff options
context:
space:
mode:
authorLogan Chien <tzuhsiang.chien@gmail.com>2015-05-29 15:33:38 +0000
committerLogan Chien <tzuhsiang.chien@gmail.com>2015-05-29 15:33:38 +0000
commit7fab97f364d2e2f0beb7fffa3e42885db72982d5 (patch)
tree87fa9f0023b1e0d4925d5435378528e150849a36 /libunwind/test
parentf4b4430f8c9c66c32a49e4c72bf594580d198501 (diff)
downloadbcm5719-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.cpp42
-rw-r--r--libunwind/test/libunwind_02.pass.cpp37
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);
+}
OpenPOWER on IntegriCloud