1 //===---------------------- backtrace_test.cpp ----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include <assert.h>
10 #include <unwind.h>
11
12 extern "C" _Unwind_Reason_Code
trace_function(struct _Unwind_Context * context,void * ntraced)13 trace_function(struct _Unwind_Context* context, void* ntraced) {
14 (*reinterpret_cast<size_t*>(ntraced))++;
15 // We should never have a call stack this deep...
16 assert(*reinterpret_cast<size_t*>(ntraced) < 20);
17 return _URC_NO_REASON;
18 }
19
call3_throw(size_t * ntraced)20 void call3_throw(size_t* ntraced) {
21 try {
22 _Unwind_Backtrace(trace_function, ntraced);
23 } catch (...) {
24 assert(false);
25 }
26 }
27
call3_nothrow(size_t * ntraced)28 void call3_nothrow(size_t* ntraced) {
29 _Unwind_Backtrace(trace_function, ntraced);
30 }
31
call2(size_t * ntraced,bool do_throw)32 void call2(size_t* ntraced, bool do_throw) {
33 if (do_throw) {
34 call3_throw(ntraced);
35 } else {
36 call3_nothrow(ntraced);
37 }
38 }
39
call1(size_t * ntraced,bool do_throw)40 void call1(size_t* ntraced, bool do_throw) {
41 call2(ntraced, do_throw);
42 }
43
main()44 int main() {
45 size_t throw_ntraced = 0;
46 size_t nothrow_ntraced = 0;
47
48 call1(¬hrow_ntraced, false);
49
50 try {
51 call1(&throw_ntraced, true);
52 } catch (...) {
53 assert(false);
54 }
55
56 // Different platforms (and different runtimes) will unwind a different number
57 // of times, so we can't make any better assumptions than this.
58 assert(nothrow_ntraced > 1);
59 assert(throw_ntraced == nothrow_ntraced); // Make sure we unwind through catch
60 return 0;
61 }
62