summaryrefslogtreecommitdiffstats
path: root/libcxxabi/test
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2014-08-29 15:26:06 +0000
committerDan Albert <danalbert@google.com>2014-08-29 15:26:06 +0000
commit2c012d495dddb382748f126d1131670801c723e0 (patch)
treeafe0d43f560765abee98c3e12d928908a1227b30 /libcxxabi/test
parentf28e7e7d34688ad6585de9c192161018cf6ef4d3 (diff)
downloadbcm5719-llvm-2c012d495dddb382748f126d1131670801c723e0.tar.gz
bcm5719-llvm-2c012d495dddb382748f126d1131670801c723e0.zip
Make _Unwind_Backtrace() work on ARM.
Summary: Since the personality functions do the actual unwinding on ARM, and will also stop unwinding when they encounter a handler, we invoke _Unwind_VRS_Interpret() directly form _Unwind_Backtrace(). To simplify, the logic for decoding an EHT is moved out of unwindOneFrame() and into its own function, decode_eht_entry(). Unlike unwindOneFrame(), which could only handle ARM's compact personality function entries (section 6.3) decode_eht_entry() can handle the generic entries (section 6.2). Reviewers: jroelofs Reviewed By: jroelofs Subscribers: piman, aemerson, cfe-commits Differential Revision: http://reviews.llvm.org/D5112 llvm-svn: 216730
Diffstat (limited to 'libcxxabi/test')
-rw-r--r--libcxxabi/test/backtrace_test.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/libcxxabi/test/backtrace_test.cpp b/libcxxabi/test/backtrace_test.cpp
new file mode 100644
index 00000000000..25dccb3229e
--- /dev/null
+++ b/libcxxabi/test/backtrace_test.cpp
@@ -0,0 +1,61 @@
+//===---------------------- backtrace_test.cpp ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <assert.h>
+#include <unwind.h>
+
+extern "C" _Unwind_Reason_Code
+trace_function(struct _Unwind_Context* context, void* ntraced) {
+ (*reinterpret_cast<size_t*>(ntraced))++;
+ // We should never have a call stack this deep...
+ assert(*reinterpret_cast<size_t*>(ntraced) < 20);
+ return _URC_NO_REASON;
+}
+
+void call3_throw(size_t* ntraced) {
+ try {
+ _Unwind_Backtrace(trace_function, ntraced);
+ } catch (...) {
+ assert(false);
+ }
+}
+
+void call3_nothrow(size_t* ntraced) {
+ _Unwind_Backtrace(trace_function, ntraced);
+}
+
+void call2(size_t* ntraced, bool do_throw) {
+ if (do_throw) {
+ call3_throw(ntraced);
+ } else {
+ call3_nothrow(ntraced);
+ }
+}
+
+void call1(size_t* ntraced, bool do_throw) {
+ call2(ntraced, do_throw);
+}
+
+int main() {
+ size_t throw_ntraced = 0;
+ size_t nothrow_ntraced = 0;
+
+ call1(&nothrow_ntraced, false);
+
+ try {
+ call1(&throw_ntraced, true);
+ } catch (...) {
+ assert(false);
+ }
+
+ // Different platforms (and different runtimes) will unwind a different number
+ // of times, so we can't make any better assumptions than this.
+ assert(nothrow_ntraced > 1);
+ assert(throw_ntraced == nothrow_ntraced); // Make sure we unwind through catch
+ return 0;
+}
OpenPOWER on IntegriCloud