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 <stddef.h> 11 #include <unwind.h> 12 13 extern "C" _Unwind_Reason_Code 14 trace_function(struct _Unwind_Context* context, void* ntraced) { 15 (*reinterpret_cast<size_t*>(ntraced))++; 16 // We should never have a call stack this deep... 17 assert(*reinterpret_cast<size_t*>(ntraced) < 20); 18 return _URC_NO_REASON; 19 } 20 21 void call3_throw(size_t* ntraced) { 22 try { 23 _Unwind_Backtrace(trace_function, ntraced); 24 } catch (...) { 25 assert(false); 26 } 27 } 28 29 void call3_nothrow(size_t* ntraced) { 30 _Unwind_Backtrace(trace_function, ntraced); 31 } 32 33 void call2(size_t* ntraced, bool do_throw) { 34 if (do_throw) { 35 call3_throw(ntraced); 36 } else { 37 call3_nothrow(ntraced); 38 } 39 } 40 41 void call1(size_t* ntraced, bool do_throw) { 42 call2(ntraced, do_throw); 43 } 44 45 int main() { 46 size_t throw_ntraced = 0; 47 size_t nothrow_ntraced = 0; 48 49 call1(¬hrow_ntraced, false); 50 51 try { 52 call1(&throw_ntraced, true); 53 } catch (...) { 54 assert(false); 55 } 56 57 // Different platforms (and different runtimes) will unwind a different number 58 // of times, so we can't make any better assumptions than this. 59 assert(nothrow_ntraced > 1); 60 assert(throw_ntraced == nothrow_ntraced); // Make sure we unwind through catch 61 return 0; 62 } 63