/*
 * OXT - OS eXtensions for boosT
 * Provides important functionality necessary for writing robust server software.
 *
 * Copyright (c) 2010 Phusion Holding B.V.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#ifndef _OXT_BACKTRACE_HPP_
#define _OXT_BACKTRACE_HPP_

/**
 * Portable C++ backtrace support.
 *
 * C++ doesn't provide a builtin, automatic, portable way of obtaining
 * backtraces. Obtaining a backtrace via a debugger (e.g. gdb) is very
 * expensive. Furthermore, not all machines have a debugger installed.
 * This makes it very hard to debug problems on production servers.
 *
 * This file provides a portable way of specifying and obtaining
 * backtraces. Via oxt::thread::all_backtraces(), it is even possible
 * to obtain the backtraces of all running threads.
 *
 * <h2>Initialization</h2>
 * Every thread that is to contain backtrace information <b>must</b> be
 * initialized. This is done by creating a `thread_local_context` object,
 * and calling `set_thread_local_context()` with that object.
 * `oxt::initialize()` automatically does this for the calling thread,
 * and `oxt::thread` does this automatically as well.
 *
 * <h2>Basic usage</h2>
 * Backtrace points must be specified manually in the code using TRACE_POINT().
 * The TracableException class allows one to obtain the backtrace at the moment
 * the exception object was created.
 *
 * For example:
 * @code
 * void foo() {
 *     TRACE_POINT();
 *     do_something();
 *     bar();
 *     do_something_else();
 * }
 *
 * void bar() {
 *     TRACE_POINT();
 *     throw TracableException();
 * }
 * @encode
 *
 * One can obtain the backtrace string, as follows:
 * @code
 * try {
 *     foo();
 * } catch (const TracableException &e) {
 *     cout << "Something bad happened:\n" << e.backtrace();
 * }
 * @endcode
 *
 * This will print something like:
 * @code
 * Something bad happened:
 *     in 'bar' (example.cpp:123)
 *     in 'foo' (example.cpp:117)
 *     in 'example_function' (example.cpp:456)
 * @encode
 *
 * <h2>Making sure the line number is correct</h2>
 * A TRACE_POINT() call will add a backtrace point for the source line on
 * which it is written. However, this causes an undesirable effect in long
 * functions:
 * @code
 * 100   void some_long_function() {
 * 101       TRACE_POINT();
 * 102       do_something();
 * 103       for (...) {
 * 104           do_something();
 * 105       }
 * 106       do_something_else();
 * 107
 * 108       if (!write_file()) {
 * 109           throw TracableException();
 * 110       }
 * 111   }
 * @endcode
 * You will want the thrown exception to show a backtrace line number that's
 * near line 109. But as things are now, the backtrace will show line 101.
 *
 * This can be solved by calling UPDATE_TRACE_POINT() from time to time:
 * @code
 * 100   void some_long_function() {
 * 101       TRACE_POINT();
 * 102       do_something();
 * 103       for (...) {
 * 104           do_something();
 * 105       }
 * 106       do_something_else();
 * 107
 * 108       if (!write_file()) {
 * 109           UPDATE_TRACE_POINT();   // Added!
 * 110           throw TracableException();
 * 111       }
 * 112   }
 * @endcode
 *
 * <h2>Compilation options</h2>
 * Define OXT_DISABLE_BACKTRACES to disable backtrace support. The backtrace
 * functions as provided by this header will become empty stubs.
 */

#if defined(NDEBUG) || defined(OXT_DISABLE_BACKTRACES)
	#include "detail/backtrace_disabled.hpp"
#else
	#include "detail/backtrace_enabled.hpp"
#endif

#endif /* _OXT_BACKTRACE_HPP_ */
