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 12extern "C" _Unwind_Reason_Code 13trace_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 20void call3_throw(size_t* ntraced) { 21 try { 22 _Unwind_Backtrace(trace_function, ntraced); 23 } catch (...) { 24 assert(false); 25 } 26} 27 28void call3_nothrow(size_t* ntraced) { 29 _Unwind_Backtrace(trace_function, ntraced); 30} 31 32void call2(size_t* ntraced, bool do_throw) { 33 if (do_throw) { 34 call3_throw(ntraced); 35 } else { 36 call3_nothrow(ntraced); 37 } 38} 39 40void call1(size_t* ntraced, bool do_throw) { 41 call2(ntraced, do_throw); 42} 43 44int 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