Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
StackTrace.hGo to the documentation of this file.00001 #ifndef INCLUDED_StackTrace_h_ 00002 #define INCLUDED_StackTrace_h_ 00003 00004 #include <stdlib.h> 00005 00006 #ifdef __cplusplus 00007 //! Holds the C-style interface for the stack trace routines 00008 namespace stacktrace { 00009 extern "C" { 00010 #endif /* __cplusplus */ 00011 00012 typedef int machineInstruction; //!< typedef in case type needs to change on other platforms (i.e. long for 64 bit architectures?) 00013 00014 //! Must be called with the object file containing debugging symbols before symbolic output can be displayed 00015 /*! @param objfile the file containing debugging symbols, in a format supported by libBFD; generally this is the executable itself (compiled with -g), so pass argv[0] 00016 * 00017 * Display done before this has been called will display numeric addresses, which may 00018 * still be decoded externally -- this is handy for embedded systems which may not be 00019 * able to hold the debugging symbols and BFD library themselves, but the numerical 00020 * values can be looked up on the desktop workstation. 00021 * @return zero on success, negative if file could not be found, positive if it could not be parsed (wrong file type) or any other internal error */ 00022 int loadStackTraceSymbols(const char* objfile); 00023 00024 //! Stores information about a single stack frame 00025 struct StackFrame { 00026 00027 //! stack pointer, points to end of stack frame 00028 void * sp; 00029 00030 #ifdef __pic__ 00031 //! return address, points to instruction being executed within current frame 00032 /*! Note that this is the address that is being returned to by the @e sub-function, 00033 * @e not the address that this frame itself is returning to. 00034 * When executing position independent code (pic), this is the address relative 00035 * to #gp. In other words, subtract this from #gp to get current memory address, 00036 * or subtract from the binary's _gp symbol to get link-time address (for looking up file/line) */ 00037 size_t ra; 00038 00039 //! global offset used in position independent code (pic) 00040 /*! subtract #ra from this to get the actual run-time memory address of the instruction */ 00041 size_t gp; 00042 00043 #else 00044 //! return address, points to instruction being executed within current frame 00045 /*! Note that this is the address that is being returned to by the @e sub-function, 00046 * @e not the address that this frame itself is returning to. */ 00047 machineInstruction * ra; 00048 #endif /* __pic__ */ 00049 00050 //! points to the caller's stack frame (stack frame of function which called this one), may be NULL or self-referential at end of list 00051 /*! a self-referential value indicates the frame is not the last on the stack, but is the last recorded. */ 00052 struct StackFrame * caller; 00053 00054 #ifdef DEBUG_STACKTRACE 00055 //! if DEBUG_STACKTRACE is defined, this field is available which, if non-zero, will cause debugging info to be displayed on each unroll 00056 int debug; 00057 #endif 00058 }; 00059 00060 00061 //! stores information about the caller's stack frame into @a frame 00062 void getCurrentStackFrame(struct StackFrame* frame); 00063 00064 //! stores information about the caller to @a curFrame into @a nextFrame 00065 /*! @return 0 if error occurred (i.e. bottom of the stack), non-zero upon success 00066 * @a nextFrame @e can be the same instance as @a curFrame, will update in place. 00067 * @a curFrame->caller will be set to @a nextFrame. */ 00068 int unrollStackFrame(struct StackFrame* curFrame, struct StackFrame* nextFrame); 00069 00070 //! frees a list of StackFrames, such as is returned by recordStackTrace 00071 void freeStackTrace(struct StackFrame* frame); 00072 00073 //! preallocates a stack trace of a particular size (doesn't actually perform a stack trace, merely allocates the linked list) 00074 /*! this is a good idea if you want to do a stack trace within an exception handler, which might have been triggered by running out of heap */ 00075 struct StackFrame* allocateStackTrace(unsigned int size); 00076 00077 //! dumps stored stack trace to stderr 00078 void displayStackTrace(const struct StackFrame* frame); 00079 00080 #ifndef __cplusplus 00081 00082 //! dumps current stack trace to stderr, up to @a limit depth and skipping the top @a skip frames 00083 /*! pass -1U for limit to request unlimited trace, and 0 to start with the function calling recordStackTrace */ 00084 void displayCurrentStackTrace(unsigned int limit, unsigned int skip); 00085 00086 //! repeatedly calls unrollStackFrame() until the root frame is reached or @a limit is hit, skipping the top @a skip frames 00087 /*! pass -1U for limit to request unlimited trace, and 0 to start with the function calling recordStackTrace */ 00088 struct StackFrame * recordStackTrace(unsigned int limit, unsigned int skip); 00089 //! repeatedly calls unrollStackFrame() until the root frame is reached or end of @a frame list is hit, skipping the top @a skip frames 00090 /*! This is handy for reusing previously allocated frames, returns the unused portion (if return value equals @a frame, none were used -- implies never cleared @a skip) */ 00091 struct StackFrame * recordOverStackTrace(struct StackFrame* frame, unsigned int skip); 00092 00093 #else /* __cplusplus */ 00094 00095 //! dumps current stack trace to stderr, up to @a limit depth and skipping the top @a skip frames 00096 /*! pass -1U for limit to request unlimited trace, and 0 to start with the function calling recordStackTrace */ 00097 void displayCurrentStackTrace(unsigned int limit=-1U, unsigned int skip=0); 00098 00099 //! repeatedly calls unrollStackFrame() until the root frame is reached or @a limit is hit, skipping the top @a skip frames 00100 /*! pass -1U for limit to request unlimited trace, and 0 to start with the function calling recordStackTrace */ 00101 struct StackFrame * recordStackTrace(unsigned int limit=-1U, unsigned int skip=0); 00102 //! repeatedly calls unrollStackFrame() until the root frame is reached or end of @a frame list is hit, skipping the top @a skip frames 00103 /*! This is handy for reusing previously allocated frames, returns the unused portion (if return value equals @a frame, none were used -- implies never cleared @a skip) */ 00104 struct StackFrame * recordOverStackTrace(struct StackFrame* frame, unsigned int skip=0); 00105 00106 } 00107 } 00108 00109 #endif /* __cplusplus */ 00110 00111 /*! @file 00112 * @brief Describes functionality for performing stack traces 00113 * @author ejt (Creator) 00114 * 00115 * $Author: ejt $ 00116 * $Name: tekkotsu-4_0 $ 00117 * $Revision: 1.6 $ 00118 * $State: Exp $ 00119 * $Date: 2006/05/02 20:46:27 $ 00120 */ 00121 #endif |
Tekkotsu v4.0 |
Generated Thu Nov 22 00:54:56 2007 by Doxygen 1.5.4 |