<html><!-- Created using the cpp_pretty_printer from the dlib C++ library. See http://dlib.net for updates. --><head><title>dlib C++ Library - stack_trace.h</title></head><body bgcolor='white'><pre> <font color='#009900'>// Copyright (C) 2008 Davis E. King (davis@dlib.net) </font><font color='#009900'>// License: Boost Software License See LICENSE.txt for the full license. </font><font color='#0000FF'>#ifndef</font> DLIB_STACK_TRACe_ <font color='#0000FF'>#define</font> DLIB_STACK_TRACe_ <font color='#009900'>/*! 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(); } !*/</font> <font color='#0000FF'>#include</font> <font color='#5555FF'><</font>string<font color='#5555FF'>></font> <font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='assert.h.html'>assert.h</a>" <font color='#009900'>// only setup the stack trace stuff if the asserts are enabled (which happens in debug mode </font><font color='#009900'>// basically). Also, this stuff doesn't work if you use NO_MAKEFILE </font><font color='#0000FF'>#if</font> defined<font face='Lucida Console'>(</font>DLIB_ENABLE_STACK_TRACE<font face='Lucida Console'>)</font> <font color='#0000FF'>#ifdef</font> NO_MAKEFILE <font color='#0000FF'>#error</font> "<font color='#CC0000'>You can't use the dlib stack trace stuff and NO_MAKEFILE at the same time</font>" <font color='#0000FF'>#endif</font> <font color='#0000FF'>namespace</font> dlib <b>{</b> <font color='#0000FF'>const</font> std::string <b><a name='get_stack_trace'></a>get_stack_trace</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <b>}</b> <font color='#009900'>// redefine the DLIB_CASSERT macro to include the stack trace </font><font color='#0000FF'>#undef</font> DLIBM_CASSERT <font color='#0000FF'>#define</font> DLIBM_CASSERT<font face='Lucida Console'>(</font>_exp,_message<font face='Lucida Console'>)</font> \ <b>{</b><font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#5555FF'>!</font><font face='Lucida Console'>(</font>_exp<font face='Lucida Console'>)</font> <font face='Lucida Console'>)</font> \ <b>{</b> \ std::ostringstream dlib_o_out; \ dlib_o_out <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>\n\nError occurred at line </font>" <font color='#5555FF'><</font><font color='#5555FF'><</font> __LINE__ <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>.\n</font>"; \ dlib_o_out <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>Error occurred in file </font>" <font color='#5555FF'><</font><font color='#5555FF'><</font> __FILE__ <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>.\n</font>"; \ dlib_o_out <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>Error occurred in function </font>" <font color='#5555FF'><</font><font color='#5555FF'><</font> DLIB_FUNCTION_NAME <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>.\n\n</font>"; \ dlib_o_out <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>Failing expression was </font>" <font color='#5555FF'><</font><font color='#5555FF'><</font> #_exp <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>.\n</font>"; \ dlib_o_out <font color='#5555FF'><</font><font color='#5555FF'><</font> _message <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>\n\n</font>"; \ dlib_o_out <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>Stack Trace: \n</font>" <font color='#5555FF'><</font><font color='#5555FF'><</font> dlib::<font color='#BB00BB'>get_stack_trace</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'><</font><font color='#5555FF'><</font> "<font color='#CC0000'>\n</font>"; \ <font color='#BB00BB'>dlib_assert_breakpoint</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; \ <font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>fatal_error</font><font face='Lucida Console'>(</font>dlib::EBROKEN_ASSERT,dlib_o_out.<font color='#BB00BB'>str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>; \ <b>}</b><b>}</b> <font color='#0000FF'>namespace</font> dlib <b>{</b> <font color='#0000FF'>class</font> <b><a name='stack_tracer'></a>stack_tracer</b> <b>{</b> <font color='#0000FF'>public</font>: <b><a name='stack_tracer'></a>stack_tracer</b> <font face='Lucida Console'>(</font> <font color='#0000FF'>const</font> <font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font> funct_name, <font color='#0000FF'>const</font> <font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font> file_name, <font color='#0000FF'>const</font> <font color='#0000FF'><u>int</u></font> line_number <font face='Lucida Console'>)</font>; ~<b><a name='stack_tracer'></a>stack_tracer</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <b>}</b>; <b>}</b> <font color='#0000FF'>#define</font> DLIB_STACK_TRACE_NAMED<font face='Lucida Console'>(</font>x<font face='Lucida Console'>)</font> dlib::stack_tracer dlib_stack_tracer_object<font face='Lucida Console'>(</font>x,__FILE__,__LINE__<font face='Lucida Console'>)</font> <font color='#0000FF'>#define</font> DLIB_STACK_TRACE dlib::stack_tracer dlib_stack_tracer_object<font face='Lucida Console'>(</font>DLIB_FUNCTION_NAME,__FILE__,__LINE__<font face='Lucida Console'>)</font> <font color='#0000FF'>#else</font> <font color='#009900'>// don't do anything if ENABLE_ASSERTS isn't defined </font><font color='#0000FF'>#define</font> DLIB_STACK_TRACE_NAMED<font face='Lucida Console'>(</font>x<font face='Lucida Console'>)</font> <font color='#0000FF'>#define</font> DLIB_STACK_TRACE <font color='#0000FF'>namespace</font> dlib <b>{</b> <font color='#0000FF'>inline</font> <font color='#0000FF'>const</font> std::string <b><a name='get_stack_trace'></a>get_stack_trace</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <b>{</b> <font color='#0000FF'>return</font> std::<font color='#BB00BB'>string</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>stack trace not enabled</font>"<font face='Lucida Console'>)</font>;<b>}</b> <b>}</b> <font color='#0000FF'>#endif</font> <font color='#0000FF'>#endif</font> <font color='#009900'>// DLIB_STACK_TRACe_ </font> </pre></body></html>