• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&nothrow_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