summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/stack_trace.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/stack_trace.h')
-rw-r--r--ml/dlib/dlib/stack_trace.h118
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_
+