Open Inventor Reference
|
00001 /* 00002 * 00003 * Copyright (C) 2004 MeVis gGmbH All Rights Reserved. 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * Further, this software is distributed without any warranty that it is 00016 * free of the rightful claim of any third person regarding infringement 00017 * or the like. Any license provided herein, whether implied or 00018 * otherwise, applies only to this software file. Patent licenses, if 00019 * any, provided herein do not apply to combinations of this program with 00020 * other software, or any other product whatsoever. 00021 * 00022 * You should have received a copy of the GNU Lesser General Public 00023 * License along with this library; if not, write to the Free Software 00024 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00025 * 00026 * Contact information: MeVis, Center for Medical Diagnostic Systems and 00027 * Visualization GmbH, Universit�tsallee 29, D-28359 Bremen, GERMANY, or: 00028 * 00029 * http://www.mevis.de 00030 * 00031 */ 00032 00033 /* 00034 * Copyright (C) 2004 MeVis Research GmbH 00035 * 00036 _______________________________________________________________________ 00037 _______________ M E V I S R E S E A R C H G M B H _______________ 00038 | 00039 | Description: 00040 | This include file contains a class to manage a buffer for a stack 00041 | and a list of string pointers for tracing debug and release code. 00042 | 00043 | Author(s) : Wolf Spindler, Felix Ritter 00044 | 00045 _______________ M E V I S R E S E A R C H G M B H _______________ 00046 _______________________________________________________________________ 00047 */ 00048 00049 #ifndef _SO_TRACE_ 00050 #define _SO_TRACE_ 00051 00052 #include <Inventor/system/SbSystem.h> 00053 #include <Inventor/SbString.h> 00054 #include <Inventor/SbTypeDefs.h> 00055 00065 00066 #if !defined(DISABLE_ERRORTRACING) 00067 00068 # define SO_TRACE_IN(__classAndMethod___) \ 00069 static const char *const __SO_TRACE_IN_STRING_BUF = __FILE__ ":" __classAndMethod___; \ 00070 SoTrace<uint16_t> __SoTraceObject(__SO_TRACE_IN_STRING_BUF, SoGlobalTraceBuffer); 00071 00072 #else 00073 00074 # define SO_TRACE_IN(__classAndMethod___) 00075 00076 #endif // DISABLE_ERRORTRACING 00077 00079 typedef uint16_t SoGlobalTraceBufferType; 00080 00081 00082 00101 00102 template <typename INDEXTYPE> class SoTraceBuffer 00103 { 00104 public: 00105 00108 inline SoTraceBuffer() { 00109 _initClass(); 00110 } 00111 00118 inline void add(const char *const traceInString) { 00126 _traceStack[_traceStackTop] = traceInString; 00127 ++_traceStackTop; 00128 00131 _traceList[_traceListEnd] = traceInString; 00132 ++_traceListEnd; 00133 } 00134 00138 inline void remove() { 00146 _traceStackTop = static_cast<INDEXTYPE>((_traceStackTop - 1) & _bufferIndexMask); 00147 00150 _traceStack[_traceStackTop] = NULL; 00151 } 00152 00155 inline INDEXTYPE getTraceStackTop() const { 00156 return _traceStackTop; 00157 } 00158 00161 inline INDEXTYPE getTraceListEnd() const { 00162 return _traceListEnd; 00163 } 00164 00166 inline const char *const *getTraceStack() const { 00167 return _traceStack; 00168 } 00169 00171 inline const char *const *getTraceList() const { 00172 return _traceList; 00173 } 00174 00176 inline SoGlobalTraceBufferType getMaxNumTraceListDumps() const { 00177 return _maxNumTraceListDumps; 00178 } 00179 00181 inline void setMaxNumTraceListDumps(SoGlobalTraceBufferType num) { 00182 _maxNumTraceListDumps = num; 00183 } 00184 00186 inline SoGlobalTraceBufferType getMaxNumTraceStackDumps() const { 00187 return _maxNumTraceStackDumps; 00188 } 00189 00191 inline void setMaxNumTraceStackDumps(SoGlobalTraceBufferType num) { 00192 _maxNumTraceStackDumps = num; 00193 } 00194 00197 SbString getTraceDumpString() const; 00198 00199 private: 00200 00203 inline void _initClass() { 00205 memset(_traceStack, 0, _numBufBytes); 00206 memset(_traceList, 0, _numBufBytes); 00207 00209 _traceStackTop = 0; 00210 _traceListEnd = 0; 00211 } 00212 00217 enum { 00218 _numBufEntries = (1L << (sizeof(INDEXTYPE) << 3)) , 00219 _numBufBytes = _numBufEntries * sizeof(const char *), 00220 _bufferIndexMask = _numBufEntries - 1 00221 }; 00222 00224 INDEXTYPE _traceStackTop; 00225 00227 INDEXTYPE _traceListEnd; 00228 00230 const char *_traceStack[_numBufEntries]; 00231 00233 const char *_traceList[_numBufEntries]; 00234 00237 SoGlobalTraceBufferType _maxNumTraceListDumps; 00238 00241 SoGlobalTraceBufferType _maxNumTraceStackDumps; 00242 }; 00243 00244 00253 00254 extern INVENTOR_API SoTraceBuffer<SoGlobalTraceBufferType> SoGlobalTraceBuffer; 00255 00256 00257 template <typename INDEXTYPE> 00258 SbString 00259 SoTraceBuffer<INDEXTYPE>::getTraceDumpString() const 00260 { 00261 try { 00263 char num[512] = ""; 00264 00265 SbString endLineStr = "\n"; 00266 00269 SbString traceListStr = ""; 00270 SoGlobalTraceBufferType indexCounter = 0; 00271 SoGlobalTraceBufferType entry = 0; 00272 00273 if((_maxNumTraceStackDumps > 0) && (getTraceStackTop() > 0)) { 00274 sprintf(num, "\nCall stack of the last %d traced functions:\n", _maxNumTraceStackDumps); 00275 traceListStr += num; 00276 00278 SoGlobalTraceBufferType stackCnt = 0; 00279 const char * const *traceStack = getTraceStack(); 00280 SoGlobalTraceBufferType stackTop = getTraceStackTop(); 00281 SoGlobalTraceBufferType stackPreTop = stackTop; 00282 stackPreTop--; 00283 indexCounter = 1; 00284 00285 for(entry = stackPreTop; (entry != stackTop) && (stackCnt < _maxNumTraceStackDumps); entry--, stackCnt++) { 00287 sprintf(num, "%5d ", indexCounter); 00288 00290 const char *entryStrPtr = traceStack[entry]; 00291 00292 if(entryStrPtr) { 00293 traceListStr += ((SbString)num); 00294 traceListStr += entryStrPtr; 00295 traceListStr += endLineStr; 00296 } 00297 00299 indexCounter++; 00300 } 00301 } 00302 00303 if(_maxNumTraceListDumps > 0) { 00304 SoGlobalTraceBufferType listCnt = 0; 00305 sprintf(num, "\nCall list of the %d most recently traced functions:\n", _maxNumTraceListDumps); 00306 traceListStr += num; 00307 SoGlobalTraceBufferType listEnd = getTraceListEnd(); 00308 SoGlobalTraceBufferType listPreEnd = listEnd; 00309 listPreEnd--; 00310 indexCounter = 1; 00311 const char * const *traceList = SoGlobalTraceBuffer.getTraceList(); 00312 entry=0; 00313 00314 for(entry = listPreEnd; (entry != listEnd) && (listCnt < _maxNumTraceListDumps); entry--, listCnt++) { 00316 sprintf(num, "%5d ", indexCounter); 00317 00319 const char *entryStrPtr = traceList[entry]; 00320 00321 if(entryStrPtr) { 00322 traceListStr += ((SbString)num); 00323 traceListStr += entryStrPtr; 00324 traceListStr += endLineStr; 00325 } 00326 00328 indexCounter++; 00329 } 00330 } 00331 00333 return traceListStr; 00334 } 00335 catch(...) { 00336 return "<Could not determine last called functions or function stack>"; 00337 } 00338 } 00339 00340 00355 00356 template <typename INDEXTYPE> class SoTrace 00357 { 00358 public: 00359 00370 inline SoTrace(const char *const traceInString, SoTraceBuffer<INDEXTYPE> &traceBuf) : _traceBuf(traceBuf) { 00372 traceBuf.add(traceInString); 00373 } 00374 00381 inline ~SoTrace() { 00382 _traceBuf.remove(); 00383 } 00384 00385 private: 00386 00390 SoTraceBuffer<INDEXTYPE> &_traceBuf; 00391 00394 inline SoTrace(const SoTrace &trace) : _traceBuf(trace._traceBuf) { 00395 } 00396 00400 inline SoTrace<INDEXTYPE> &operator=(const SoTrace &trace) { 00401 return *this; 00402 } 00403 }; 00404 00405 #endif // _SO_TYPE_