Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | /* API for getting a stack trace of the C/C++ stack on the current thread */ |
michael@0 | 7 | |
michael@0 | 8 | #ifndef nsStackWalk_h_ |
michael@0 | 9 | #define nsStackWalk_h_ |
michael@0 | 10 | |
michael@0 | 11 | /* WARNING: This file is intended to be included from C or C++ files. */ |
michael@0 | 12 | |
michael@0 | 13 | #include "nscore.h" |
michael@0 | 14 | #include <stdint.h> |
michael@0 | 15 | |
michael@0 | 16 | #ifdef __cplusplus |
michael@0 | 17 | extern "C" { |
michael@0 | 18 | #endif |
michael@0 | 19 | |
michael@0 | 20 | // aSP will be the best approximation possible of what the stack pointer will be |
michael@0 | 21 | // pointing to when the execution returns to executing that at that PC. |
michael@0 | 22 | // If no approximation can be made it will be nullptr. |
michael@0 | 23 | typedef void |
michael@0 | 24 | (* NS_WalkStackCallback)(void *aPC, void *aSP, void *aClosure); |
michael@0 | 25 | |
michael@0 | 26 | /** |
michael@0 | 27 | * Call aCallback for the C/C++ stack frames on the current thread, from |
michael@0 | 28 | * the caller of NS_StackWalk to main (or above). |
michael@0 | 29 | * |
michael@0 | 30 | * @param aCallback Callback function, called once per frame. |
michael@0 | 31 | * @param aSkipFrames Number of initial frames to skip. 0 means that |
michael@0 | 32 | * the first callback will be for the caller of |
michael@0 | 33 | * NS_StackWalk. |
michael@0 | 34 | * @param aMaxFrames Maximum number of frames to trace. 0 means no limit. |
michael@0 | 35 | * @param aClosure Caller-supplied data passed through to aCallback. |
michael@0 | 36 | * @param aThread The thread for which the stack is to be retrieved. |
michael@0 | 37 | * Passing null causes us to walk the stack of the |
michael@0 | 38 | * current thread. On Windows, this is a thread HANDLE. |
michael@0 | 39 | * It is currently not supported on any other platform. |
michael@0 | 40 | * @param aPlatformData Platform specific data that can help in walking the |
michael@0 | 41 | * stack, this should be nullptr unless you really know |
michael@0 | 42 | * what you're doing! This needs to be a pointer to a |
michael@0 | 43 | * CONTEXT on Windows and should not be passed on other |
michael@0 | 44 | * platforms. |
michael@0 | 45 | * |
michael@0 | 46 | * Return values: |
michael@0 | 47 | * - NS_ERROR_NOT_IMPLEMENTED. Occurs on platforms where it is unimplemented. |
michael@0 | 48 | * |
michael@0 | 49 | * - NS_ERROR_UNEXPECTED. Occurs when the stack indicates that the thread |
michael@0 | 50 | * is in a very dangerous situation (e.g., holding sem_pool_lock in Mac OS X |
michael@0 | 51 | * pthreads code). Callers should then bail out immediately. |
michael@0 | 52 | * |
michael@0 | 53 | * - NS_ERROR_FAILURE. Occurs when stack walking completely failed, i.e. |
michael@0 | 54 | * aCallback was never called. |
michael@0 | 55 | * |
michael@0 | 56 | * - NS_OK. Occurs when stack walking succeeded, i.e. aCallback was called at |
michael@0 | 57 | * least once (and there was no need to exit with NS_ERROR_UNEXPECTED). |
michael@0 | 58 | * |
michael@0 | 59 | * May skip some stack frames due to compiler optimizations or code |
michael@0 | 60 | * generation. |
michael@0 | 61 | */ |
michael@0 | 62 | XPCOM_API(nsresult) |
michael@0 | 63 | NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames, |
michael@0 | 64 | uint32_t aMaxFrames, void *aClosure, uintptr_t aThread, |
michael@0 | 65 | void *aPlatformData); |
michael@0 | 66 | |
michael@0 | 67 | typedef struct { |
michael@0 | 68 | /* |
michael@0 | 69 | * The name of the shared library or executable containing an |
michael@0 | 70 | * address and the address's offset within that library, or empty |
michael@0 | 71 | * string and zero if unknown. |
michael@0 | 72 | */ |
michael@0 | 73 | char library[256]; |
michael@0 | 74 | ptrdiff_t loffset; |
michael@0 | 75 | /* |
michael@0 | 76 | * The name of the file name and line number of the code |
michael@0 | 77 | * corresponding to the address, or empty string and zero if |
michael@0 | 78 | * unknown. |
michael@0 | 79 | */ |
michael@0 | 80 | char filename[256]; |
michael@0 | 81 | unsigned long lineno; |
michael@0 | 82 | /* |
michael@0 | 83 | * The name of the function containing an address and the address's |
michael@0 | 84 | * offset within that function, or empty string and zero if unknown. |
michael@0 | 85 | */ |
michael@0 | 86 | char function[256]; |
michael@0 | 87 | ptrdiff_t foffset; |
michael@0 | 88 | } nsCodeAddressDetails; |
michael@0 | 89 | |
michael@0 | 90 | /** |
michael@0 | 91 | * For a given pointer to code, fill in the pieces of information used |
michael@0 | 92 | * when printing a stack trace. |
michael@0 | 93 | * |
michael@0 | 94 | * @param aPC The code address. |
michael@0 | 95 | * @param aDetails A structure to be filled in with the result. |
michael@0 | 96 | */ |
michael@0 | 97 | XPCOM_API(nsresult) |
michael@0 | 98 | NS_DescribeCodeAddress(void *aPC, nsCodeAddressDetails *aDetails); |
michael@0 | 99 | |
michael@0 | 100 | /** |
michael@0 | 101 | * Format the information about a code address in a format suitable for |
michael@0 | 102 | * stack traces on the current platform. When available, this string |
michael@0 | 103 | * should contain the function name, source file, and line number. When |
michael@0 | 104 | * these are not available, library and offset should be reported, if |
michael@0 | 105 | * possible. |
michael@0 | 106 | * |
michael@0 | 107 | * @param aPC The code address. |
michael@0 | 108 | * @param aDetails The value filled in by NS_DescribeCodeAddress(aPC). |
michael@0 | 109 | * @param aBuffer A string to be filled in with the description. |
michael@0 | 110 | * The string will always be null-terminated. |
michael@0 | 111 | * @param aBufferSize The size, in bytes, of aBuffer, including |
michael@0 | 112 | * room for the terminating null. If the information |
michael@0 | 113 | * to be printed would be larger than aBuffer, it |
michael@0 | 114 | * will be truncated so that aBuffer[aBufferSize-1] |
michael@0 | 115 | * is the terminating null. |
michael@0 | 116 | */ |
michael@0 | 117 | XPCOM_API(nsresult) |
michael@0 | 118 | NS_FormatCodeAddressDetails(void *aPC, const nsCodeAddressDetails *aDetails, |
michael@0 | 119 | char *aBuffer, uint32_t aBufferSize); |
michael@0 | 120 | |
michael@0 | 121 | #ifdef __cplusplus |
michael@0 | 122 | } |
michael@0 | 123 | #endif |
michael@0 | 124 | |
michael@0 | 125 | #endif /* !defined(nsStackWalk_h_) */ |