|
Sierra Toolkit
Version of the Day
|
00001 #ifndef STK_UTIL_DIAG_TRACE_HPP 00002 #define STK_UTIL_DIAG_TRACE_HPP 00003 00004 #include <cstring> 00005 #include <vector> 00006 #include <map> 00007 #include <string> 00008 #include <functional> 00009 00010 #include <stk_util/diag/Writer_fwd.hpp> 00011 00012 00013 #define SLIB_TRACE_COVERAGE 00014 00015 namespace stk { 00016 namespace diag { 00017 00022 00031 class Tracespec 00032 { 00033 public: 00040 explicit Tracespec(const char *function_spec) 00041 : m_functionSpec(function_spec) 00042 {} 00043 00049 inline const char *getFunctionSpec() const { 00050 return m_functionSpec; 00051 } 00052 00058 std::string getFunctionName() const; 00059 00065 std::string getFunctionShortName() const; 00066 00072 std::string getFunctionClass() const; 00073 00079 std::string getFunctionNamespace() const; 00080 00086 std::string getFunctionShortClass() const; 00087 00088 protected: 00089 const char * m_functionSpec; 00090 }; 00091 00092 typedef std::vector<const char *> TracebackStack; 00093 00101 class Traceback : public Tracespec 00102 { 00103 public: 00113 enum TracebackState{RUNNING, THROWING}; 00114 00115 enum {STACK_SIZE = 2048}; 00116 typedef const char *Stack[STACK_SIZE] ; 00117 typedef const char * const * const_stack_iterator; 00118 typedef const char ** stack_iterator; 00119 00128 typedef std::map<const char *, int> Coverage; 00129 00135 class Preserve 00136 { 00137 public: 00143 Preserve() { 00144 Traceback::preserveStack(); 00145 } 00146 00151 ~Preserve() { 00152 Traceback::releaseStack(); 00153 } 00154 }; 00155 00162 explicit Traceback(const char *function_spec) 00163 : Tracespec(function_spec) 00164 { 00165 if (s_top >= &s_stack[STACK_SIZE - 1] || s_top == 0) 00166 s_top = s_stack; 00167 *s_top++ = function_spec; 00168 00169 if (s_tracebackState == THROWING && !s_tracebackPreserve && !std::uncaught_exception()) 00170 s_tracebackState = RUNNING; 00171 } 00172 00173 00179 ~Traceback() { 00180 if (!s_tracebackPreserve && std::uncaught_exception() && s_tracebackState == RUNNING) { 00181 s_tracebackState = THROWING; 00182 s_storedTop = s_storedStack + (s_top - s_stack); 00183 std::copy(s_stack, s_top, s_storedStack); 00184 } 00185 if (s_top > &s_stack[0]) 00186 --s_top; 00187 } 00188 00189 static TracebackStack snapshot(); 00190 00196 inline static void enableTracebackDisplay() { 00197 --s_tracebackDisplay; 00198 } 00199 00205 inline static void disableTracebackDisplay() { 00206 ++s_tracebackDisplay; 00207 } 00208 00216 inline static bool displayTraceback() { 00217 return s_tracebackDisplay == 0; 00218 } 00219 00225 inline static void preserveStack() { 00226 ++s_tracebackPreserve; 00227 } 00228 00234 inline static void releaseStack() { 00235 --s_tracebackPreserve; 00236 } 00237 00244 inline static TracebackState getTracebackState() { 00245 return s_tracebackState; 00246 } 00247 00257 static std::string printTraceback(const TracebackStack &traceback_stack); 00258 00259 private: 00260 static TracebackState s_tracebackState; 00261 static int s_tracebackPreserve; 00262 static int s_tracebackDisplay; 00263 static const char ** s_top; 00264 static Stack s_stack; 00265 static const char ** s_storedTop; 00266 static Stack s_storedStack; 00267 }; 00268 00269 00281 class Trace : public Traceback 00282 { 00283 public: 00289 typedef Writer & (*ExtraFuncPtr)(Writer &); 00290 00295 struct TraceList : public std::vector<const char *> { 00296 public: 00297 TraceList() { 00298 s_traceListExists = true; 00299 } 00300 00301 ~TraceList() { 00302 s_traceListExists = false; 00303 } 00304 }; 00305 00310 enum { 00311 IN_TRACE_LIST = 0x01 00312 }; 00313 00331 Trace(Writer &dout, const char *function_name, int print_mask = LOG_TRACE, bool do_trace = true); 00332 00338 ~Trace(); 00339 00349 inline static ExtraFuncPtr setExtra(ExtraFuncPtr extra) { 00350 ExtraFuncPtr x = s_extra; 00351 s_extra = extra; 00352 return x; 00353 } 00354 00362 inline static void addTraceFunction(const std::string &function_prefix) { 00363 char *s = std::strcpy(new char[function_prefix.length() + 1], function_prefix.c_str()); 00364 00365 s_traceList.push_back(s); 00366 } 00367 00373 inline static void clearTraceFunctions() { 00374 for (std::vector<const char *>::iterator it = s_traceList.begin(); it != s_traceList.end(); ++it) 00375 delete[] (*it); 00376 00377 s_traceList.clear(); 00378 } 00379 00388 Writer &verbose_print(Writer &dout) const; 00389 00390 private: 00391 Writer & m_diagWriter; 00392 double m_startCpuTime; 00393 size_t m_startMemAlloc; 00394 PrintMask m_lineMask; 00395 bool m_do_trace; 00396 int m_flags; 00397 00398 static ExtraFuncPtr s_extra; 00399 static TraceList s_traceList; 00400 static bool s_traceListExists; 00401 }; 00402 00416 inline Writer &operator<<(Writer &dout, const Trace &diag_trace) { 00417 return diag_trace.verbose_print(dout); 00418 } 00419 00420 } // namespace diag 00421 } // namespace stk 00422 00426 00427 #endif // STK_UTIL_DIAG_TRACE_HPP