From ebeea3fa9992d5ceb71806b24ae94c8601638717 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 27 May 2019 22:43:59 +0300 Subject: Add backtrace() --- tests/backtrace/driver.cxx | 97 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/backtrace/driver.cxx (limited to 'tests/backtrace/driver.cxx') diff --git a/tests/backtrace/driver.cxx b/tests/backtrace/driver.cxx new file mode 100644 index 0000000..5fd9223 --- /dev/null +++ b/tests/backtrace/driver.cxx @@ -0,0 +1,97 @@ +// file : tests/backtrace/driver.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef _WIN32 +# include // setrlimit() +#endif + +#include + +#ifndef __cpp_lib_modules_ts +#include +#include +#include // set_terminate(), terminate_handler +#include +#else +import std.io; +#endif + +// Other includes. + +#ifdef __cpp_modules_ts +#ifdef __cpp_lib_modules_ts +import std.core; +#endif +import butl.process; +import butl.backtrace; +#else +#include +#include +#endif + +using namespace std; +using namespace butl; + +namespace test +{ + // Note: is not static to make sure the stack frame is not optimized out. + // + int + func () + { + throw system_error (EINVAL, generic_category ()); + } +} + +static terminate_handler def_term_handler; + +// Usage: argv[0] [-c] +// +// Print the backtrace for an unhandled exception. +// +// -c +// Run as a child process that sets up the backtrace-printing terminate +// handler and throws unhandled exception. +int +main (int argc, const char* argv[]) +{ + // Not to cause the testscript to fail due to the abnormal test driver + // termination, delegate the unhandled exception backtrace printing to the + // child process. + // + bool child (false); + for (int i (1); i != argc; ++i) + { + string o (argv[i]); + + if (o == "-c") + child = true; + else + assert (false); + } + + if (child) + { + // Disable dumping core file on POSIX. + // +#ifndef _WIN32 + struct rlimit rlim {0, 0}; + assert (setrlimit (RLIMIT_CORE, &rlim) == 0); +#endif + + def_term_handler = set_terminate ([]() + { + cerr << backtrace (); + + if (def_term_handler != nullptr) + def_term_handler (); + }); + + return test::func (); + } + + // Report failure with non-zero code if child succeeds. + // + return process_run (0, 1, 2, argv[0], "-c") ? 1 : 0; +} -- cgit v1.1