diff options
Diffstat (limited to 'ml/dlib/dlib/stack_trace.h')
-rw-r--r-- | ml/dlib/dlib/stack_trace.h | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/ml/dlib/dlib/stack_trace.h b/ml/dlib/dlib/stack_trace.h new file mode 100644 index 000000000..aacbeb782 --- /dev/null +++ b/ml/dlib/dlib/stack_trace.h @@ -0,0 +1,118 @@ +// Copyright (C) 2008 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_STACK_TRACe_ +#define DLIB_STACK_TRACe_ + +/*! + This file defines 3 things. Two of them are preprocessor macros that + enable you to tag functions with the dlib stack trace watcher. The + third thing is a function named get_stack_trace() which returns the + current stack trace in std::string form. + + To enable the stack trace you must #define DLIB_ENABLE_STACK_TRACE. + When this #define isn't set then the 3 things described above + still exist but they don't do anything. + + Also note that when the stack trace is enabled it changes the DLIB_ASSERT + and DLIB_CASSERT macros so that they print stack traces when + an assert fails. + + See the following example program for details: + + #include <iostream> + #include <dlib/stack_trace.h> + + void funct2() + { + // put this macro at the top of each function you would + // like to appear in stack traces + DLIB_STACK_TRACE; + + // you may print the current stack trace as follows. + std::cout << dlib::get_stack_trace() << endl; + } + + void funct() + { + // This alternate form of DLIB_STACK_TRACE allows you to specify + // the string used to name the current function. The other form + // will usually output an appropriate function name automatically + // so this may not be needed. + DLIB_STACK_TRACE_NAMED("funct"); + funct2(); + } + + int main() + { + funct(); + } +!*/ + + +#include <string> +#include "assert.h" + +// only setup the stack trace stuff if the asserts are enabled (which happens in debug mode +// basically). Also, this stuff doesn't work if you use NO_MAKEFILE +#if defined(DLIB_ENABLE_STACK_TRACE) +#ifdef NO_MAKEFILE +#error "You can't use the dlib stack trace stuff and NO_MAKEFILE at the same time" +#endif + +namespace dlib +{ + const std::string get_stack_trace(); +} + +// redefine the DLIB_CASSERT macro to include the stack trace +#undef DLIBM_CASSERT +#define DLIBM_CASSERT(_exp,_message) \ + {if ( !(_exp) ) \ + { \ + std::ostringstream dlib_o_out; \ + dlib_o_out << "\n\nError occurred at line " << __LINE__ << ".\n"; \ + dlib_o_out << "Error occurred in file " << __FILE__ << ".\n"; \ + dlib_o_out << "Error occurred in function " << DLIB_FUNCTION_NAME << ".\n\n"; \ + dlib_o_out << "Failing expression was " << #_exp << ".\n"; \ + dlib_o_out << _message << "\n\n"; \ + dlib_o_out << "Stack Trace: \n" << dlib::get_stack_trace() << "\n"; \ + dlib_assert_breakpoint(); \ + throw dlib::fatal_error(dlib::EBROKEN_ASSERT,dlib_o_out.str()); \ + }} + + + +namespace dlib +{ + + class stack_tracer + { + public: + stack_tracer ( + const char* funct_name, + const char* file_name, + const int line_number + ); + + ~stack_tracer(); + + }; +} + +#define DLIB_STACK_TRACE_NAMED(x) dlib::stack_tracer dlib_stack_tracer_object(x,__FILE__,__LINE__) +#define DLIB_STACK_TRACE dlib::stack_tracer dlib_stack_tracer_object(DLIB_FUNCTION_NAME,__FILE__,__LINE__) + +#else // don't do anything if ENABLE_ASSERTS isn't defined +#define DLIB_STACK_TRACE_NAMED(x) +#define DLIB_STACK_TRACE + +namespace dlib +{ + inline const std::string get_stack_trace() { return std::string("stack trace not enabled");} +} + +#endif + + +#endif // DLIB_STACK_TRACe_ + |