michael@0: /* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* API for getting a stack trace of the C/C++ stack on the current thread */ michael@0: michael@0: #ifndef nsStackWalk_h_ michael@0: #define nsStackWalk_h_ michael@0: michael@0: /* WARNING: This file is intended to be included from C or C++ files. */ michael@0: michael@0: #include "nscore.h" michael@0: #include michael@0: michael@0: #ifdef __cplusplus michael@0: extern "C" { michael@0: #endif michael@0: michael@0: // aSP will be the best approximation possible of what the stack pointer will be michael@0: // pointing to when the execution returns to executing that at that PC. michael@0: // If no approximation can be made it will be nullptr. michael@0: typedef void michael@0: (* NS_WalkStackCallback)(void *aPC, void *aSP, void *aClosure); michael@0: michael@0: /** michael@0: * Call aCallback for the C/C++ stack frames on the current thread, from michael@0: * the caller of NS_StackWalk to main (or above). michael@0: * michael@0: * @param aCallback Callback function, called once per frame. michael@0: * @param aSkipFrames Number of initial frames to skip. 0 means that michael@0: * the first callback will be for the caller of michael@0: * NS_StackWalk. michael@0: * @param aMaxFrames Maximum number of frames to trace. 0 means no limit. michael@0: * @param aClosure Caller-supplied data passed through to aCallback. michael@0: * @param aThread The thread for which the stack is to be retrieved. michael@0: * Passing null causes us to walk the stack of the michael@0: * current thread. On Windows, this is a thread HANDLE. michael@0: * It is currently not supported on any other platform. michael@0: * @param aPlatformData Platform specific data that can help in walking the michael@0: * stack, this should be nullptr unless you really know michael@0: * what you're doing! This needs to be a pointer to a michael@0: * CONTEXT on Windows and should not be passed on other michael@0: * platforms. michael@0: * michael@0: * Return values: michael@0: * - NS_ERROR_NOT_IMPLEMENTED. Occurs on platforms where it is unimplemented. michael@0: * michael@0: * - NS_ERROR_UNEXPECTED. Occurs when the stack indicates that the thread michael@0: * is in a very dangerous situation (e.g., holding sem_pool_lock in Mac OS X michael@0: * pthreads code). Callers should then bail out immediately. michael@0: * michael@0: * - NS_ERROR_FAILURE. Occurs when stack walking completely failed, i.e. michael@0: * aCallback was never called. michael@0: * michael@0: * - NS_OK. Occurs when stack walking succeeded, i.e. aCallback was called at michael@0: * least once (and there was no need to exit with NS_ERROR_UNEXPECTED). michael@0: * michael@0: * May skip some stack frames due to compiler optimizations or code michael@0: * generation. michael@0: */ michael@0: XPCOM_API(nsresult) michael@0: NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames, michael@0: uint32_t aMaxFrames, void *aClosure, uintptr_t aThread, michael@0: void *aPlatformData); michael@0: michael@0: typedef struct { michael@0: /* michael@0: * The name of the shared library or executable containing an michael@0: * address and the address's offset within that library, or empty michael@0: * string and zero if unknown. michael@0: */ michael@0: char library[256]; michael@0: ptrdiff_t loffset; michael@0: /* michael@0: * The name of the file name and line number of the code michael@0: * corresponding to the address, or empty string and zero if michael@0: * unknown. michael@0: */ michael@0: char filename[256]; michael@0: unsigned long lineno; michael@0: /* michael@0: * The name of the function containing an address and the address's michael@0: * offset within that function, or empty string and zero if unknown. michael@0: */ michael@0: char function[256]; michael@0: ptrdiff_t foffset; michael@0: } nsCodeAddressDetails; michael@0: michael@0: /** michael@0: * For a given pointer to code, fill in the pieces of information used michael@0: * when printing a stack trace. michael@0: * michael@0: * @param aPC The code address. michael@0: * @param aDetails A structure to be filled in with the result. michael@0: */ michael@0: XPCOM_API(nsresult) michael@0: NS_DescribeCodeAddress(void *aPC, nsCodeAddressDetails *aDetails); michael@0: michael@0: /** michael@0: * Format the information about a code address in a format suitable for michael@0: * stack traces on the current platform. When available, this string michael@0: * should contain the function name, source file, and line number. When michael@0: * these are not available, library and offset should be reported, if michael@0: * possible. michael@0: * michael@0: * @param aPC The code address. michael@0: * @param aDetails The value filled in by NS_DescribeCodeAddress(aPC). michael@0: * @param aBuffer A string to be filled in with the description. michael@0: * The string will always be null-terminated. michael@0: * @param aBufferSize The size, in bytes, of aBuffer, including michael@0: * room for the terminating null. If the information michael@0: * to be printed would be larger than aBuffer, it michael@0: * will be truncated so that aBuffer[aBufferSize-1] michael@0: * is the terminating null. michael@0: */ michael@0: XPCOM_API(nsresult) michael@0: NS_FormatCodeAddressDetails(void *aPC, const nsCodeAddressDetails *aDetails, michael@0: char *aBuffer, uint32_t aBufferSize); michael@0: michael@0: #ifdef __cplusplus michael@0: } michael@0: #endif michael@0: michael@0: #endif /* !defined(nsStackWalk_h_) */