1605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert//===---------------------- backtrace_test.cpp ----------------------------===// 2605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert// 3605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert// The LLVM Compiler Infrastructure 4605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert// 5605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert// This file is dual licensed under the MIT and the University of Illinois Open 6605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert// Source Licenses. See LICENSE.TXT for details. 7605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert// 8605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert//===----------------------------------------------------------------------===// 9605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert#include <assert.h> 10605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert#include <unwind.h> 11605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 12605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albertextern "C" _Unwind_Reason_Code 13605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Alberttrace_function(struct _Unwind_Context* context, void* ntraced) { 14605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert (*reinterpret_cast<size_t*>(ntraced))++; 15605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert // We should never have a call stack this deep... 16605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert assert(*reinterpret_cast<size_t*>(ntraced) < 20); 17605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert return _URC_NO_REASON; 18605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert} 19605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 20605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albertvoid call3_throw(size_t* ntraced) { 21605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert try { 22605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert _Unwind_Backtrace(trace_function, ntraced); 23605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert } catch (...) { 24605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert assert(false); 25605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert } 26605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert} 27605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 28605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albertvoid call3_nothrow(size_t* ntraced) { 29605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert _Unwind_Backtrace(trace_function, ntraced); 30605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert} 31605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 32605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albertvoid call2(size_t* ntraced, bool do_throw) { 33605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert if (do_throw) { 34605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert call3_throw(ntraced); 35605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert } else { 36605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert call3_nothrow(ntraced); 37605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert } 38605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert} 39605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 40605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albertvoid call1(size_t* ntraced, bool do_throw) { 41605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert call2(ntraced, do_throw); 42605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert} 43605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 44605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albertint main() { 45605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert size_t throw_ntraced = 0; 46605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert size_t nothrow_ntraced = 0; 47605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 48605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert call1(¬hrow_ntraced, false); 49605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 50605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert try { 51605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert call1(&throw_ntraced, true); 52605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert } catch (...) { 53605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert assert(false); 54605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert } 55605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert 56605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert // Different platforms (and different runtimes) will unwind a different number 57605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert // of times, so we can't make any better assumptions than this. 58605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert assert(nothrow_ntraced > 1); 59605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert assert(throw_ntraced == nothrow_ntraced); // Make sure we unwind through catch 60605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert return 0; 61605f03260ce43ec564cd0ec80ea21514e82eeeb3Dan Albert} 62