StackWalk.h (9311B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* APIs for getting a stack trace of the current thread */ 8 9 #ifndef mozilla_StackWalk_h 10 #define mozilla_StackWalk_h 11 12 #include "mozilla/Types.h" 13 #include <stdint.h> 14 #include <stdio.h> 15 16 MOZ_BEGIN_EXTERN_C 17 18 /** 19 * Returns the position of the Program Counter for the caller of the current 20 * function. This is meant to be used to feed the aFirstFramePC argument to 21 * MozStackWalk or MozWalkTheStack*, and should be used in the last function 22 * that should be skipped in the trace, and passed down to MozStackWalk or 23 * MozWalkTheStack*, through any intermediaries. 24 * 25 * THIS DOES NOT 100% RELIABLY GIVE THE CALLER PC, but marking functions 26 * calling this macro with MOZ_NEVER_INLINE gets us close. In cases it doesn't 27 * give the caller's PC, it may give the caller of the caller, or its caller, 28 * etc. depending on tail call optimization. 29 * 30 * Past versions of stackwalking relied on passing a constant number of frames 31 * to skip to MozStackWalk or MozWalkTheStack, which fell short in more cases 32 * (inlining of intermediaries, tail call optimization). 33 */ 34 #define CallerPC() __builtin_extract_return_addr(__builtin_return_address(0)) 35 36 /** 37 * The callback for MozStackWalk and MozStackWalkThread. 38 * 39 * @param aFrameNumber The frame number (starts at 1, not 0). 40 * @param aPC The program counter value. 41 * @param aSP The best approximation possible of what the stack 42 * pointer will be pointing to when the execution returns 43 * to executing that at aPC. If no approximation can 44 * be made it will be nullptr. 45 * @param aClosure Extra data passed in from MozStackWalk() or 46 * MozStackWalkThread(). 47 */ 48 typedef void (*MozWalkStackCallback)(uint32_t aFrameNumber, void* aPC, 49 void* aSP, void* aClosure); 50 51 /** 52 * Call aCallback for each stack frame on the current thread, from 53 * the caller of MozStackWalk to main (or above). 54 * 55 * @param aCallback Callback function, called once per frame. 56 * @param aFirstFramePC Position of the Program Counter where the trace 57 * starts from. All frames seen before reaching that 58 * address are skipped. Nullptr means that the first 59 * callback will be for the caller of MozStackWalk. 60 * @param aMaxFrames Maximum number of frames to trace. 0 means no limit. 61 * @param aClosure Caller-supplied data passed through to aCallback. 62 * 63 * May skip some stack frames due to compiler optimizations or code 64 * generation. 65 */ 66 MFBT_API void MozStackWalk(MozWalkStackCallback aCallback, 67 const void* aFirstFramePC, uint32_t aMaxFrames, 68 void* aClosure); 69 70 typedef struct { 71 /* 72 * The name of the shared library or executable containing an 73 * address and the address's offset within that library, or empty 74 * string and zero if unknown. 75 */ 76 char library[256]; 77 ptrdiff_t loffset; 78 /* 79 * The name of the file name and line number of the code 80 * corresponding to the address, or empty string and zero if 81 * unknown. 82 */ 83 char filename[256]; 84 unsigned long lineno; 85 /* 86 * The name of the function containing an address and the address's 87 * offset within that function, or empty string and zero if unknown. 88 */ 89 char function[256]; 90 ptrdiff_t foffset; 91 } MozCodeAddressDetails; 92 93 /** 94 * For a given pointer to code, fill in the pieces of information used 95 * when printing a stack trace. 96 * 97 * @param aPC The code address. 98 * @param aDetails A structure to be filled in with the result. 99 */ 100 MFBT_API bool MozDescribeCodeAddress(void* aPC, 101 MozCodeAddressDetails* aDetails); 102 103 /** 104 * Format the information about a code address in a format suitable for 105 * stack traces on the current platform. When available, this string 106 * should contain the function name, source file, and line number. When 107 * these are not available, library and offset should be reported, if 108 * possible. 109 * 110 * Note that this output is parsed by several scripts including the fix*.py and 111 * make-tree.pl scripts in tools/rb/. It should only be change with care, and 112 * in conjunction with those scripts. 113 * 114 * @param aBuffer A string to be filled in with the description. 115 * The string will always be null-terminated. 116 * @param aBufferSize The size, in bytes, of aBuffer, including 117 * room for the terminating null. If the information 118 * to be printed would be larger than aBuffer, it 119 * will be truncated so that aBuffer[aBufferSize-1] 120 * is the terminating null. 121 * @param aFrameNumber The frame number. 122 * @param aPC The code address. 123 * @param aFunction The function name. Possibly null or the empty string. 124 * @param aLibrary The library name. Possibly null or the empty string. 125 * @param aLOffset The library offset. 126 * @param aFileName The filename. Possibly null or the empty string. 127 * @param aLineNo The line number. Possibly zero. 128 * @return The minimum number of characters necessary to format 129 * the frame information, without the terminating null. 130 * The buffer will have been truncated if the returned 131 * value is greater than aBufferSize-1. 132 */ 133 MFBT_API int MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize, 134 uint32_t aFrameNumber, const void* aPC, 135 const char* aFunction, const char* aLibrary, 136 ptrdiff_t aLOffset, const char* aFileName, 137 uint32_t aLineNo); 138 139 /** 140 * Format the information about a code address in the same fashion as 141 * MozFormatCodeAddress. 142 * 143 * @param aBuffer A string to be filled in with the description. 144 * The string will always be null-terminated. 145 * @param aBufferSize The size, in bytes, of aBuffer, including 146 * room for the terminating null. If the information 147 * to be printed would be larger than aBuffer, it 148 * will be truncated so that aBuffer[aBufferSize-1] 149 * is the terminating null. 150 * @param aFrameNumber The frame number. 151 * @param aPC The code address. 152 * @param aDetails The value filled in by MozDescribeCodeAddress(aPC). 153 * @return The minimum number of characters necessary to format 154 * the frame information, without the terminating null. 155 * The buffer will have been truncated if the returned 156 * value is greater than aBufferSize-1. 157 */ 158 MFBT_API int MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize, 159 uint32_t aFrameNumber, void* aPC, 160 const MozCodeAddressDetails* aDetails); 161 162 #ifdef __cplusplus 163 # define FRAMES_DEFAULT = 0 164 #else 165 # define FRAMES_DEFAULT 166 #endif 167 /** 168 * Walk the stack and print the stack trace to the given stream. 169 * 170 * @param aStream A stdio stream. 171 * @param aFirstFramePC Position of the Program Counter where the trace 172 * starts from. All frames seen before reaching that 173 * address are skipped. Nullptr means that the first 174 * callback will be for the caller of MozWalkTheStack. 175 * @param aMaxFrames Maximum number of frames to trace. 0 means no limit. 176 */ 177 MFBT_API void MozWalkTheStack(FILE* aStream, 178 const void* aFirstFramePC FRAMES_DEFAULT, 179 uint32_t aMaxFrames FRAMES_DEFAULT); 180 181 /** 182 * Walk the stack and send each stack trace line to a callback writer. 183 * Each line string is null terminated but doesn't contain a '\n' character. 184 * 185 * @param aWriter The callback. 186 * @param aFirstFramePC Position of the Program Counter where the trace 187 * starts from. All frames seen before reaching that 188 * address are skipped. Nullptr means that the first 189 * callback will be for the caller of 190 * MozWalkTheStackWithWriter. 191 * @param aMaxFrames Maximum number of frames to trace. 0 means no limit. 192 */ 193 MFBT_API void MozWalkTheStackWithWriter( 194 void (*aWriter)(const char*), const void* aFirstFramePC FRAMES_DEFAULT, 195 uint32_t aMaxFrames FRAMES_DEFAULT); 196 197 #undef FRAMES_DEFAULT 198 199 MOZ_END_EXTERN_C 200 201 #ifdef __cplusplus 202 namespace mozilla { 203 204 MFBT_API void FramePointerStackWalk(MozWalkStackCallback aCallback, 205 uint32_t aMaxFrames, void* aClosure, 206 void** aBp, void* aStackEnd); 207 208 # if defined(XP_LINUX) || defined(XP_FREEBSD) 209 MFBT_API void DemangleSymbol(const char* aSymbol, char* aBuffer, int aBufLen); 210 # endif 211 212 } // namespace mozilla 213 #endif 214 215 #endif