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