mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1172216 - Move nsStackwalk to mozglue. r=glandium
This commit is contained in:
parent
aace26e2a9
commit
9b4532466d
@ -27,7 +27,7 @@
|
||||
#endif
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Vector.h"
|
||||
@ -123,7 +123,7 @@ static bool gIsDMDInitialized = false;
|
||||
// - Indirect allocations in js::{Vector,HashSet,HashMap} -- this class serves
|
||||
// as their AllocPolicy.
|
||||
//
|
||||
// - Other indirect allocations (e.g. NS_StackWalk) -- see the comments on
|
||||
// - Other indirect allocations (e.g. MozStackWalk) -- see the comments on
|
||||
// Thread::mBlockIntercepts and in replace_malloc for how these work.
|
||||
//
|
||||
// It would be nice if we could use the InfallibleAllocPolicy from mozalloc,
|
||||
@ -512,7 +512,7 @@ class Thread
|
||||
// When true, this blocks intercepts, which allows malloc interception
|
||||
// functions to themselves call malloc. (Nb: for direct calls to malloc we
|
||||
// can just use InfallibleAllocPolicy::{malloc_,new_}, but we sometimes
|
||||
// indirectly call vanilla malloc via functions like NS_StackWalk.)
|
||||
// indirectly call vanilla malloc via functions like MozStackWalk.)
|
||||
bool mBlockIntercepts;
|
||||
|
||||
Thread()
|
||||
@ -735,40 +735,23 @@ StackTrace::Get(Thread* aT)
|
||||
MOZ_ASSERT(gStateLock->IsLocked());
|
||||
MOZ_ASSERT(aT->InterceptsAreBlocked());
|
||||
|
||||
// On Windows, NS_StackWalk can acquire a lock from the shared library
|
||||
// On Windows, MozStackWalk can acquire a lock from the shared library
|
||||
// loader. Another thread might call malloc while holding that lock (when
|
||||
// loading a shared library). So we can't be in gStateLock during the call
|
||||
// to NS_StackWalk. For details, see
|
||||
// to MozStackWalk. For details, see
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=374829#c8
|
||||
// On Linux, something similar can happen; see bug 824340.
|
||||
// So let's just release it on all platforms.
|
||||
nsresult rv;
|
||||
StackTrace tmp;
|
||||
{
|
||||
AutoUnlockState unlock;
|
||||
uint32_t skipFrames = 2;
|
||||
rv = NS_StackWalk(StackWalkCallback, skipFrames,
|
||||
gOptions->MaxFrames(), &tmp, 0, nullptr);
|
||||
}
|
||||
|
||||
if (rv == NS_OK) {
|
||||
// Handle the common case first. All is ok. Nothing to do.
|
||||
} else if (rv == NS_ERROR_NOT_IMPLEMENTED || rv == NS_ERROR_FAILURE) {
|
||||
tmp.mLength = 0;
|
||||
} else if (rv == NS_ERROR_UNEXPECTED) {
|
||||
// XXX: This |rv| only happens on Mac, and it indicates that we're handling
|
||||
// a call to malloc that happened inside a mutex-handling function. Any
|
||||
// attempt to create a semaphore (which can happen in printf) could
|
||||
// deadlock.
|
||||
//
|
||||
// However, the most complex thing DMD does after Get() returns is to put
|
||||
// something in a hash table, which might call
|
||||
// InfallibleAllocPolicy::malloc_. I'm not yet sure if this needs special
|
||||
// handling, hence the forced abort. Sorry. If you hit this, please file
|
||||
// a bug and CC nnethercote.
|
||||
MOZ_CRASH("unexpected case in StackTrace::Get()");
|
||||
} else {
|
||||
MOZ_CRASH("impossible case in StackTrace::Get()");
|
||||
if (MozStackWalk(StackWalkCallback, skipFrames,
|
||||
gOptions->MaxFrames(), &tmp, 0, nullptr)) {
|
||||
// Handle the common case first. All is ok. Nothing to do.
|
||||
} else {
|
||||
tmp.mLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
StackTraceTable::AddPtr p = gStackTraceTable->lookupForAdd(&tmp);
|
||||
@ -1232,7 +1215,7 @@ replace_malloc(size_t aSize)
|
||||
Thread* t = Thread::Fetch();
|
||||
if (t->InterceptsAreBlocked()) {
|
||||
// Intercepts are blocked, which means this must be a call to malloc
|
||||
// triggered indirectly by DMD (e.g. via NS_StackWalk). Be infallible.
|
||||
// triggered indirectly by DMD (e.g. via MozStackWalk). Be infallible.
|
||||
return InfallibleAllocPolicy::malloc_(aSize);
|
||||
}
|
||||
|
||||
@ -1555,9 +1538,9 @@ Init(const malloc_table_t* aMallocTable)
|
||||
// (prior to the creation of any mutexes, apparently) otherwise we can get
|
||||
// hangs when getting stack traces (bug 821577). But
|
||||
// StackWalkInitCriticalAddress() isn't exported from xpcom/, so instead we
|
||||
// just call NS_StackWalk, because that calls StackWalkInitCriticalAddress().
|
||||
// just call MozStackWalk, because that calls StackWalkInitCriticalAddress().
|
||||
// See the comment above StackWalkInitCriticalAddress() for more details.
|
||||
(void)NS_StackWalk(NopStackWalkCallback, /* skipFrames */ 0,
|
||||
(void)MozStackWalk(NopStackWalkCallback, /* skipFrames */ 0,
|
||||
/* maxFrames */ 1, nullptr, 0, nullptr);
|
||||
#endif
|
||||
|
||||
|
@ -13,7 +13,7 @@ EXPORTS += [
|
||||
SOURCES += [
|
||||
'../../../mfbt/HashFunctions.cpp',
|
||||
'../../../mfbt/JSONWriter.cpp',
|
||||
'../../../xpcom/base/nsStackWalk.cpp',
|
||||
'../../../mozglue/misc/StackWalk.cpp',
|
||||
'DMD.cpp',
|
||||
]
|
||||
|
||||
|
@ -9,9 +9,6 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#include "nsStackWalkPrivate.h"
|
||||
|
||||
#include "nsStackWalk.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
@ -38,16 +35,16 @@ static CriticalAddress gCriticalAddress;
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#define NSSTACKWALK_SUPPORTS_MACOSX \
|
||||
#define MOZ_STACKWALK_SUPPORTS_MACOSX \
|
||||
(defined(XP_DARWIN) && \
|
||||
(defined(__i386) || defined(__ppc__) || defined(HAVE__UNWIND_BACKTRACE)))
|
||||
|
||||
#define NSSTACKWALK_SUPPORTS_LINUX \
|
||||
#define MOZ_STACKWALK_SUPPORTS_LINUX \
|
||||
(defined(linux) && \
|
||||
((defined(__GNUC__) && (defined(__i386) || defined(PPC))) || \
|
||||
defined(HAVE__UNWIND_BACKTRACE)))
|
||||
|
||||
#if NSSTACKWALK_SUPPORTS_MACOSX
|
||||
#if MOZ_STACKWALK_SUPPORTS_MACOSX
|
||||
#include <pthread.h>
|
||||
#include <sys/errno.h>
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
@ -110,7 +107,7 @@ my_malloc_logger(uint32_t aType,
|
||||
// On Leopard dladdr returns the wrong value for "new_sem_from_pool". The
|
||||
// stack shows up as having two pthread_cond_wait$UNIX2003 frames.
|
||||
const char* name = "new_sem_from_pool";
|
||||
NS_StackWalk(stack_callback, /* skipFrames */ 0, /* maxFrames */ 0,
|
||||
MozStackWalk(stack_callback, /* skipFrames */ 0, /* maxFrames */ 0,
|
||||
const_cast<char*>(name), 0, nullptr);
|
||||
}
|
||||
|
||||
@ -121,7 +118,7 @@ my_malloc_logger(uint32_t aType,
|
||||
// function during NS_LogInit() ensures that we meet the first criterion, and
|
||||
// running this function during the stack walking functions ensures we meet the
|
||||
// second criterion.
|
||||
void
|
||||
MFBT_API void
|
||||
StackWalkInitCriticalAddress()
|
||||
{
|
||||
if (gCriticalAddress.mInit) {
|
||||
@ -181,7 +178,7 @@ IsCriticalAddress(void* aPC)
|
||||
// We still initialize gCriticalAddress.mInit so that this code behaves
|
||||
// the same on all platforms. Otherwise a failure to init would be visible
|
||||
// only on OS X.
|
||||
void
|
||||
MFBT_API void
|
||||
StackWalkInitCriticalAddress()
|
||||
{
|
||||
gCriticalAddress.mInit = true;
|
||||
@ -190,15 +187,12 @@ StackWalkInitCriticalAddress()
|
||||
|
||||
#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64)) // WIN32 x86 stack walking code
|
||||
|
||||
#include "nscore.h"
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include "plstr.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
#include "nspr.h"
|
||||
#include <imagehlp.h>
|
||||
// We need a way to know if we are building for WXP (or later), as if we are, we
|
||||
// need to use the newer 64-bit APIs. API_VERSION_NUMBER seems to fit the bill.
|
||||
@ -512,8 +506,8 @@ WalkStackThread(void* aData)
|
||||
* whose in memory address doesn't match its in-file address.
|
||||
*/
|
||||
|
||||
XPCOM_API(nsresult)
|
||||
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
MFBT_API bool
|
||||
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
|
||||
void* aPlatformData)
|
||||
{
|
||||
@ -524,7 +518,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
struct WalkStackData data;
|
||||
|
||||
if (!EnsureWalkThreadReady()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE currentThread = ::GetCurrentThread();
|
||||
@ -542,7 +536,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
if (data.walkCallingThread) {
|
||||
PrintError("DuplicateHandle (process)");
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!::DuplicateHandle(::GetCurrentProcess(),
|
||||
@ -553,7 +547,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
if (data.walkCallingThread) {
|
||||
PrintError("DuplicateHandle (thread)");
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
return false;
|
||||
}
|
||||
|
||||
data.skipFrames = aSkipFrames;
|
||||
@ -622,7 +616,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
(*aCallback)(i + 1, data.pcs[i], data.sps[i], aClosure);
|
||||
}
|
||||
|
||||
return data.pc_count == 0 ? NS_ERROR_FAILURE : NS_OK;
|
||||
return data.pc_count != 0;
|
||||
}
|
||||
|
||||
|
||||
@ -772,8 +766,8 @@ EnsureSymInitialized()
|
||||
}
|
||||
|
||||
|
||||
XPCOM_API(nsresult)
|
||||
NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
|
||||
MFBT_API bool
|
||||
MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails)
|
||||
{
|
||||
aDetails->library[0] = '\0';
|
||||
aDetails->loffset = 0;
|
||||
@ -783,7 +777,7 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
|
||||
aDetails->foffset = 0;
|
||||
|
||||
if (!EnsureSymInitialized()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE myProcess = ::GetCurrentProcess();
|
||||
@ -804,12 +798,12 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
|
||||
modInfoRes = SymGetModuleInfoEspecial64(myProcess, addr, &modInfo, &lineInfo);
|
||||
|
||||
if (modInfoRes) {
|
||||
PL_strncpyz(aDetails->library, modInfo.ModuleName,
|
||||
strncpy(aDetails->library, modInfo.ModuleName,
|
||||
sizeof(aDetails->library));
|
||||
aDetails->loffset = (char*)aPC - (char*)modInfo.BaseOfImage;
|
||||
|
||||
if (lineInfo.FileName) {
|
||||
PL_strncpyz(aDetails->filename, lineInfo.FileName,
|
||||
strncpy(aDetails->filename, lineInfo.FileName,
|
||||
sizeof(aDetails->filename));
|
||||
aDetails->lineno = lineInfo.LineNumber;
|
||||
}
|
||||
@ -825,23 +819,21 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
|
||||
ok = SymFromAddr(myProcess, addr, &displacement, pSymbol);
|
||||
|
||||
if (ok) {
|
||||
PL_strncpyz(aDetails->function, pSymbol->Name,
|
||||
strncpy(aDetails->function, pSymbol->Name,
|
||||
sizeof(aDetails->function));
|
||||
aDetails->foffset = static_cast<ptrdiff_t>(displacement);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&gDbgHelpCS); // release our lock
|
||||
return NS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
// i386 or PPC Linux stackwalking code
|
||||
#elif HAVE_DLADDR && (HAVE__UNWIND_BACKTRACE || NSSTACKWALK_SUPPORTS_LINUX || NSSTACKWALK_SUPPORTS_MACOSX)
|
||||
#elif HAVE_DLADDR && (HAVE__UNWIND_BACKTRACE || MOZ_STACKWALK_SUPPORTS_LINUX || MOZ_STACKWALK_SUPPORTS_MACOSX)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "nscore.h"
|
||||
#include <stdio.h>
|
||||
#include "plstr.h"
|
||||
|
||||
// On glibc 2.1, the Dl_info api defined in <dlfcn.h> is only exposed
|
||||
// if __USE_GNU is defined. I suppose its some kind of standards
|
||||
@ -868,7 +860,7 @@ void DemangleSymbol(const char* aSymbol,
|
||||
char* demangled = abi::__cxa_demangle(aSymbol, 0, 0, 0);
|
||||
|
||||
if (demangled) {
|
||||
PL_strncpyz(aBuffer, demangled, aBufLen);
|
||||
strncpy(aBuffer, demangled, aBufLen);
|
||||
free(demangled);
|
||||
}
|
||||
#endif // MOZ_DEMANGLE_SYMBOLS
|
||||
@ -884,8 +876,8 @@ void DemangleSymbol(const char* aSymbol,
|
||||
extern MOZ_EXPORT void* __libc_stack_end; // from ld-linux.so
|
||||
#endif
|
||||
namespace mozilla {
|
||||
nsresult
|
||||
FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
bool
|
||||
FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
uint32_t aMaxFrames, void* aClosure, void** bp,
|
||||
void* aStackEnd)
|
||||
{
|
||||
@ -915,7 +907,7 @@ FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
bp += 2;
|
||||
#endif
|
||||
if (IsCriticalAddress(pc)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
return false;
|
||||
}
|
||||
if (--skip < 0) {
|
||||
// Assume that the SP points to the BP of the function
|
||||
@ -930,16 +922,16 @@ FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
}
|
||||
bp = next;
|
||||
}
|
||||
return numFrames == 0 ? NS_ERROR_FAILURE : NS_OK;
|
||||
return numFrames != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define X86_OR_PPC (defined(__i386) || defined(PPC) || defined(__ppc__))
|
||||
#if X86_OR_PPC && (NSSTACKWALK_SUPPORTS_MACOSX || NSSTACKWALK_SUPPORTS_LINUX) // i386 or PPC Linux or Mac stackwalking code
|
||||
#if X86_OR_PPC && (MOZ_STACKWALK_SUPPORTS_MACOSX || MOZ_STACKWALK_SUPPORTS_LINUX) // i386 or PPC Linux or Mac stackwalking code
|
||||
|
||||
XPCOM_API(nsresult)
|
||||
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
MFBT_API bool
|
||||
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
|
||||
void* aPlatformData)
|
||||
{
|
||||
@ -975,7 +967,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
|
||||
struct unwind_info
|
||||
{
|
||||
NS_WalkStackCallback callback;
|
||||
MozWalkStackCallback callback;
|
||||
int skip;
|
||||
int maxFrames;
|
||||
int numFrames;
|
||||
@ -1007,8 +999,8 @@ unwind_callback(struct _Unwind_Context* context, void* closure)
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
XPCOM_API(nsresult)
|
||||
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
MFBT_API bool
|
||||
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
|
||||
void* aPlatformData)
|
||||
{
|
||||
@ -1034,15 +1026,15 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
// is to make unwind_callback return something other than _URC_NO_REASON,
|
||||
// which causes _Unwind_Backtrace to return a non-success code.
|
||||
if (info.isCriticalAbort) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
return false;
|
||||
}
|
||||
return info.numFrames == 0 ? NS_ERROR_FAILURE : NS_OK;
|
||||
return info.numFrames != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
XPCOM_API(nsresult)
|
||||
NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
|
||||
bool MFBT_API
|
||||
MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails)
|
||||
{
|
||||
aDetails->library[0] = '\0';
|
||||
aDetails->loffset = 0;
|
||||
@ -1054,51 +1046,51 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
|
||||
Dl_info info;
|
||||
int ok = dladdr(aPC, &info);
|
||||
if (!ok) {
|
||||
return NS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
PL_strncpyz(aDetails->library, info.dli_fname, sizeof(aDetails->library));
|
||||
strncpy(aDetails->library, info.dli_fname, sizeof(aDetails->library));
|
||||
aDetails->loffset = (char*)aPC - (char*)info.dli_fbase;
|
||||
|
||||
const char* symbol = info.dli_sname;
|
||||
if (!symbol || symbol[0] == '\0') {
|
||||
return NS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
DemangleSymbol(symbol, aDetails->function, sizeof(aDetails->function));
|
||||
|
||||
if (aDetails->function[0] == '\0') {
|
||||
// Just use the mangled symbol if demangling failed.
|
||||
PL_strncpyz(aDetails->function, symbol, sizeof(aDetails->function));
|
||||
strncpy(aDetails->function, symbol, sizeof(aDetails->function));
|
||||
}
|
||||
|
||||
aDetails->foffset = (char*)aPC - (char*)info.dli_saddr;
|
||||
return NS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
#else // unsupported platform.
|
||||
|
||||
XPCOM_API(nsresult)
|
||||
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
MFBT_API bool
|
||||
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
|
||||
void* aPlatformData)
|
||||
{
|
||||
MOZ_ASSERT(!aThread);
|
||||
MOZ_ASSERT(!aPlatformData);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
nsresult
|
||||
FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
MFBT_API bool
|
||||
FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
void* aClosure, void** aBp)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
XPCOM_API(nsresult)
|
||||
NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
|
||||
MFBT_API bool
|
||||
MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails)
|
||||
{
|
||||
aDetails->library[0] = '\0';
|
||||
aDetails->loffset = 0;
|
||||
@ -1106,24 +1098,24 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
|
||||
aDetails->lineno = 0;
|
||||
aDetails->function[0] = '\0';
|
||||
aDetails->foffset = 0;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_FormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
|
||||
MFBT_API void
|
||||
MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
|
||||
uint32_t aFrameNumber, void* aPC,
|
||||
const nsCodeAddressDetails* aDetails)
|
||||
const MozCodeAddressDetails* aDetails)
|
||||
{
|
||||
NS_FormatCodeAddress(aBuffer, aBufferSize,
|
||||
MozFormatCodeAddress(aBuffer, aBufferSize,
|
||||
aFrameNumber, aPC, aDetails->function,
|
||||
aDetails->library, aDetails->loffset,
|
||||
aDetails->filename, aDetails->lineno);
|
||||
}
|
||||
|
||||
XPCOM_API(void)
|
||||
NS_FormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
|
||||
MFBT_API void
|
||||
MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
|
||||
const void* aPC, const char* aFunction,
|
||||
const char* aLibrary, ptrdiff_t aLOffset,
|
||||
const char* aFileName, uint32_t aLineNo)
|
@ -6,20 +6,16 @@
|
||||
|
||||
/* API for getting a stack trace of the C/C++ stack on the current thread */
|
||||
|
||||
#ifndef nsStackWalk_h_
|
||||
#define nsStackWalk_h_
|
||||
#ifndef mozilla_StackWalk_h
|
||||
#define mozilla_StackWalk_h
|
||||
|
||||
/* WARNING: This file is intended to be included from C or C++ files. */
|
||||
|
||||
#include "nscore.h"
|
||||
#include "mozilla/Types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The callback for NS_StackWalk.
|
||||
* The callback for MozStackWalk.
|
||||
*
|
||||
* @param aFrameNumber The frame number (starts at 1, not 0).
|
||||
* @param aPC The program counter value.
|
||||
@ -27,20 +23,20 @@ extern "C" {
|
||||
* pointer will be pointing to when the execution returns
|
||||
* to executing that at aPC. If no approximation can
|
||||
* be made it will be nullptr.
|
||||
* @param aClosure Extra data passed in via NS_StackWalk().
|
||||
* @param aClosure Extra data passed in via MozStackWalk().
|
||||
*/
|
||||
typedef void
|
||||
(*NS_WalkStackCallback)(uint32_t aFrameNumber, void* aPC, void* aSP,
|
||||
(*MozWalkStackCallback)(uint32_t aFrameNumber, void* aPC, void* aSP,
|
||||
void* aClosure);
|
||||
|
||||
/**
|
||||
* Call aCallback for the C/C++ stack frames on the current thread, from
|
||||
* the caller of NS_StackWalk to main (or above).
|
||||
* the caller of MozStackWalk to main (or above).
|
||||
*
|
||||
* @param aCallback Callback function, called once per frame.
|
||||
* @param aSkipFrames Number of initial frames to skip. 0 means that
|
||||
* the first callback will be for the caller of
|
||||
* NS_StackWalk.
|
||||
* MozStackWalk.
|
||||
* @param aMaxFrames Maximum number of frames to trace. 0 means no limit.
|
||||
* @param aClosure Caller-supplied data passed through to aCallback.
|
||||
* @param aThread The thread for which the stack is to be retrieved.
|
||||
@ -53,27 +49,14 @@ typedef void
|
||||
* CONTEXT on Windows and should not be passed on other
|
||||
* platforms.
|
||||
*
|
||||
* Return values:
|
||||
* - NS_ERROR_NOT_IMPLEMENTED. Occurs on platforms where it is unimplemented.
|
||||
*
|
||||
* - NS_ERROR_UNEXPECTED. Occurs when the stack indicates that the thread
|
||||
* is in a very dangerous situation (e.g., holding sem_pool_lock in Mac OS X
|
||||
* pthreads code). Callers should then bail out immediately.
|
||||
*
|
||||
* - NS_ERROR_FAILURE. Occurs when stack walking completely failed, i.e.
|
||||
* aCallback was never called.
|
||||
*
|
||||
* - NS_OK. Occurs when stack walking succeeded, i.e. aCallback was called at
|
||||
* least once (and there was no need to exit with NS_ERROR_UNEXPECTED).
|
||||
*
|
||||
* May skip some stack frames due to compiler optimizations or code
|
||||
* generation.
|
||||
*
|
||||
* Note: this (and other helper methods) will only be available when
|
||||
* MOZ_STACKWALKING is defined, so any new consumers must #if based on that.
|
||||
*/
|
||||
XPCOM_API(nsresult)
|
||||
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
MFBT_API bool
|
||||
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
|
||||
void* aPlatformData);
|
||||
|
||||
@ -99,7 +82,7 @@ typedef struct
|
||||
*/
|
||||
char function[256];
|
||||
ptrdiff_t foffset;
|
||||
} nsCodeAddressDetails;
|
||||
} MozCodeAddressDetails;
|
||||
|
||||
/**
|
||||
* For a given pointer to code, fill in the pieces of information used
|
||||
@ -108,8 +91,8 @@ typedef struct
|
||||
* @param aPC The code address.
|
||||
* @param aDetails A structure to be filled in with the result.
|
||||
*/
|
||||
XPCOM_API(nsresult)
|
||||
NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails);
|
||||
MFBT_API bool
|
||||
MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails);
|
||||
|
||||
/**
|
||||
* Format the information about a code address in a format suitable for
|
||||
@ -137,15 +120,15 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails);
|
||||
* @param aFileName The filename. Possibly null or the empty string.
|
||||
* @param aLineNo The line number. Possibly zero.
|
||||
*/
|
||||
XPCOM_API(void)
|
||||
NS_FormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
|
||||
MFBT_API void
|
||||
MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
|
||||
const void* aPC, const char* aFunction,
|
||||
const char* aLibrary, ptrdiff_t aLOffset,
|
||||
const char* aFileName, uint32_t aLineNo);
|
||||
|
||||
/**
|
||||
* Format the information about a code address in the same fashion as
|
||||
* NS_FormatCodeAddress.
|
||||
* MozFormatCodeAddress.
|
||||
*
|
||||
* @param aBuffer A string to be filled in with the description.
|
||||
* The string will always be null-terminated.
|
||||
@ -156,15 +139,27 @@ NS_FormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
|
||||
* is the terminating null.
|
||||
* @param aFrameNumber The frame number.
|
||||
* @param aPC The code address.
|
||||
* @param aDetails The value filled in by NS_DescribeCodeAddress(aPC).
|
||||
* @param aDetails The value filled in by MozDescribeCodeAddress(aPC).
|
||||
*/
|
||||
XPCOM_API(void)
|
||||
NS_FormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
|
||||
MFBT_API void
|
||||
MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
|
||||
uint32_t aFrameNumber, void* aPC,
|
||||
const nsCodeAddressDetails* aDetails);
|
||||
const MozCodeAddressDetails* aDetails);
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MFBT_API bool
|
||||
FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
uint32_t aMaxFrames, void* aClosure, void** aBp,
|
||||
void* aStackEnd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(nsStackWalk_h_) */
|
||||
/**
|
||||
* Initialize the critical sections for this platform so that we can
|
||||
* abort stack walks when needed.
|
||||
*/
|
||||
MFBT_API void
|
||||
StackWalkInitCriticalAddress(void);
|
||||
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
FINAL_LIBRARY = 'mozglue'
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'StackWalk.h',
|
||||
'TimeStamp.h',
|
||||
]
|
||||
|
||||
@ -21,6 +22,7 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
SOURCES += [
|
||||
'TimeStamp_windows.cpp',
|
||||
]
|
||||
OS_LIBS += ['dbghelp']
|
||||
elif CONFIG['HAVE_CLOCK_MONOTONIC']:
|
||||
SOURCES += [
|
||||
'TimeStamp_posix.cpp',
|
||||
@ -32,4 +34,14 @@ elif CONFIG['OS_ARCH'] == 'Darwin':
|
||||
elif CONFIG['COMPILE_ENVIRONMENT']:
|
||||
error('No TimeStamp implementation on this platform. Build will not succeed')
|
||||
|
||||
# MOZ_STACKWALKING is defined in configure.in when the build configuration meets
|
||||
# the conditions for GeckoStackWalk to work correctly.
|
||||
# We exclude this file from other build configurations so that if somebody adds a
|
||||
# new usage of NS_StackWalk it will cause a link error, which is better than having
|
||||
# GeckoStackWalk silently return garbage at runtime.
|
||||
if CONFIG['MOZ_STACKWALKING']:
|
||||
SOURCES += [
|
||||
'StackWalk.cpp',
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#ifdef MOZ_STACKWALKING
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#endif
|
||||
|
||||
#define TARGET_SANDBOX_EXPORT __declspec(dllexport)
|
||||
@ -63,10 +63,10 @@ StackFrameToOStringStream(uint32_t aFrameNumber, void* aPC, void* aSP,
|
||||
void* aClosure)
|
||||
{
|
||||
std::ostringstream* stream = static_cast<std::ostringstream*>(aClosure);
|
||||
nsCodeAddressDetails details;
|
||||
MozCodeAddressDetails details;
|
||||
char buf[1024];
|
||||
NS_DescribeCodeAddress(aPC, &details);
|
||||
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
|
||||
MozDescribeCodeAddress(aPC, &details);
|
||||
MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
|
||||
*stream << std::endl << "--" << buf;
|
||||
stream->flush();
|
||||
}
|
||||
@ -90,7 +90,7 @@ Log(const char* aMessageType,
|
||||
if (aShouldLogStackTrace) {
|
||||
if (sStackTraceDepth) {
|
||||
msgStream << std::endl << "Stack Trace:";
|
||||
NS_StackWalk(StackFrameToOStringStream, aFramesToSkip, sStackTraceDepth,
|
||||
MozStackWalk(StackFrameToOStringStream, aFramesToSkip, sStackTraceDepth,
|
||||
&msgStream, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
@ -77,10 +77,10 @@ static void SandboxPrintStackFrame(uint32_t aFrameNumber, void *aPC, void *aSP,
|
||||
void *aClosure)
|
||||
{
|
||||
char buf[1024];
|
||||
nsCodeAddressDetails details;
|
||||
MozCodeAddressDetails details;
|
||||
|
||||
NS_DescribeCodeAddress(aPC, &details);
|
||||
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
|
||||
MozDescribeCodeAddress(aPC, &details);
|
||||
MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
|
||||
SANDBOX_LOG_ERROR("frame %s", buf);
|
||||
}
|
||||
|
||||
@ -90,11 +90,11 @@ SandboxLogCStack()
|
||||
// Skip 3 frames: one for this module, one for the signal handler in
|
||||
// libmozsandbox, and one for the signal trampoline.
|
||||
//
|
||||
// Warning: this might not print any stack frames. NS_StackWalk
|
||||
// Warning: this might not print any stack frames. MozStackWalk
|
||||
// can't walk past the signal trampoline on ARM (bug 968531), and
|
||||
// x86 frame pointer walking may or may not work (bug 1082276).
|
||||
|
||||
NS_StackWalk(SandboxPrintStackFrame, /* skip */ 3, /* max */ 0,
|
||||
MozStackWalk(SandboxPrintStackFrame, /* skip */ 3, /* max */ 0,
|
||||
nullptr, 0, nullptr);
|
||||
SANDBOX_LOG_ERROR("end of stack.");
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ static unsigned int _gdb_sleep_duration = 300;
|
||||
|
||||
#include <unistd.h>
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
|
||||
// NB: keep me up to date with the same variable in
|
||||
// ipc/chromium/chrome/common/ipc_channel_posix.cc
|
||||
@ -68,10 +68,10 @@ static void PrintStackFrame(uint32_t aFrameNumber, void *aPC, void *aSP,
|
||||
void *aClosure)
|
||||
{
|
||||
char buf[1024];
|
||||
nsCodeAddressDetails details;
|
||||
MozCodeAddressDetails details;
|
||||
|
||||
NS_DescribeCodeAddress(aPC, &details);
|
||||
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
|
||||
MozDescribeCodeAddress(aPC, &details);
|
||||
MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
|
||||
fprintf(stdout, "%s\n", buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
@ -87,7 +87,7 @@ ah_crap_handler(int signum)
|
||||
signum);
|
||||
|
||||
printf("Stack:\n");
|
||||
NS_StackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0,
|
||||
MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0,
|
||||
nullptr, 0, nullptr);
|
||||
|
||||
printf("Sleeping for %d seconds.\n",_gdb_sleep_duration);
|
||||
|
@ -49,9 +49,6 @@
|
||||
#if defined(MOZ_PROFILING) && (defined(XP_MACOSX) || defined(XP_WIN))
|
||||
#define USE_NS_STACKWALK
|
||||
#endif
|
||||
#ifdef USE_NS_STACKWALK
|
||||
#include "nsStackWalk.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
typedef CONTEXT tickcontext_t;
|
||||
@ -880,7 +877,7 @@ void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample
|
||||
};
|
||||
|
||||
// Start with the current function. We use 0 as the frame number here because
|
||||
// the FramePointerStackWalk() and NS_StackWalk() calls below will use 1..N.
|
||||
// the FramePointerStackWalk() and MozStackWalk() calls below will use 1..N.
|
||||
// This is a bit weird but it doesn't matter because StackWalkCallback()
|
||||
// doesn't use the frame number argument.
|
||||
StackWalkCallback(/* frameNumber */ 0, aSample->pc, aSample->sp, &nativeStack);
|
||||
@ -891,7 +888,7 @@ void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample
|
||||
void *stackEnd = reinterpret_cast<void*>(-1);
|
||||
if (pt)
|
||||
stackEnd = static_cast<char*>(pthread_get_stackaddr_np(pt));
|
||||
nsresult rv = NS_OK;
|
||||
bool rv = true;
|
||||
if (aSample->fp >= aSample->sp && aSample->fp <= stackEnd)
|
||||
rv = FramePointerStackWalk(StackWalkCallback, /* skipFrames */ 0,
|
||||
maxFrames, &nativeStack,
|
||||
@ -900,17 +897,17 @@ void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample
|
||||
void *platformData = nullptr;
|
||||
#ifdef XP_WIN
|
||||
if (aSample->isSamplingCurrentThread) {
|
||||
// In this case we want NS_StackWalk to know that it's walking the
|
||||
// In this case we want MozStackWalk to know that it's walking the
|
||||
// current thread's stack, so we pass 0 as the thread handle.
|
||||
thread = 0;
|
||||
}
|
||||
platformData = aSample->context;
|
||||
#endif // XP_WIN
|
||||
|
||||
nsresult rv = NS_StackWalk(StackWalkCallback, /* skipFrames */ 0, maxFrames,
|
||||
bool rv = MozStackWalk(StackWalkCallback, /* skipFrames */ 0, maxFrames,
|
||||
&nativeStack, thread, platformData);
|
||||
#endif
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (rv)
|
||||
mergeStacksIntoProfile(aProfile, aSample, nativeStack);
|
||||
}
|
||||
#endif
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -27,7 +27,7 @@ namespace mozilla {
|
||||
// while |free| is used to free strings created by |copy|.
|
||||
//
|
||||
// |DescribeCodeAddressLock| is needed when the callers may be holding a lock
|
||||
// used by NS_DescribeCodeAddress. |DescribeCodeAddressLock| must implement
|
||||
// used by MozDescribeCodeAddress. |DescribeCodeAddressLock| must implement
|
||||
// static methods IsLocked(), Unlock() and Lock().
|
||||
template <class StringTable,
|
||||
class StringAlloc,
|
||||
@ -35,9 +35,9 @@ template <class StringTable,
|
||||
class CodeAddressService
|
||||
{
|
||||
// GetLocation() is the key function in this class. It's basically a wrapper
|
||||
// around NS_DescribeCodeAddress.
|
||||
// around MozDescribeCodeAddress.
|
||||
//
|
||||
// However, NS_DescribeCodeAddress is very slow on some platforms, and we
|
||||
// However, MozDescribeCodeAddress is very slow on some platforms, and we
|
||||
// have lots of repeated (i.e. same PC) calls to it. So we do some caching
|
||||
// of results. Each cached result includes two strings (|mFunction| and
|
||||
// |mLibrary|), so we also optimize them for space in the following ways.
|
||||
@ -137,15 +137,15 @@ public:
|
||||
if (!entry.mInUse || entry.mPc != aPc) {
|
||||
mNumCacheMisses++;
|
||||
|
||||
// NS_DescribeCodeAddress can (on Linux) acquire a lock inside
|
||||
// MozDescribeCodeAddress can (on Linux) acquire a lock inside
|
||||
// the shared library loader. Another thread might call malloc
|
||||
// while holding that lock (when loading a shared library). So
|
||||
// we have to exit the lock around this call. For details, see
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=363334#c3
|
||||
nsCodeAddressDetails details;
|
||||
MozCodeAddressDetails details;
|
||||
{
|
||||
DescribeCodeAddressLock::Unlock();
|
||||
(void)NS_DescribeCodeAddress(const_cast<void*>(aPc), &details);
|
||||
(void)MozDescribeCodeAddress(const_cast<void*>(aPc), &details);
|
||||
DescribeCodeAddressLock::Lock();
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ public:
|
||||
|
||||
MOZ_ASSERT(entry.mPc == aPc);
|
||||
|
||||
NS_FormatCodeAddress(aBuf, aBufLen, aFrameNumber, entry.mPc,
|
||||
MozFormatCodeAddress(aBuf, aBufLen, aFrameNumber, entry.mPc,
|
||||
entry.mFunction, entry.mLibrary, entry.mLOffset,
|
||||
entry.mFileName, entry.mLineNo);
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* API for getting a stack trace of the C/C++ */
|
||||
|
||||
#ifndef StackWalk_h_
|
||||
#define StackWalk_h_
|
||||
|
||||
// XXX: it would be nice to eventually remove this header dependency on nsStackWalk.h
|
||||
#include "nsStackWalk.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nsresult
|
||||
FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
|
||||
uint32_t aMaxFrames, void* aClosure, void** aBp,
|
||||
void* aStackEnd);
|
||||
|
||||
}
|
||||
|
||||
#endif /* !defined(StackWalk_h_) */
|
@ -56,7 +56,6 @@ EXPORTS += [
|
||||
'nsObjCExceptions.h',
|
||||
'nsQueryObject.h',
|
||||
'nsRefPtr.h',
|
||||
'nsStackWalk.h',
|
||||
'nsTraceRefcnt.h',
|
||||
'nsWeakPtr.h',
|
||||
]
|
||||
@ -78,7 +77,6 @@ EXPORTS.mozilla += [
|
||||
'HoldDropJSObjects.h',
|
||||
'LinuxUtils.h',
|
||||
'nsMemoryInfoDumper.h',
|
||||
'StackWalk.h',
|
||||
'StaticMutex.h',
|
||||
'StaticPtr.h',
|
||||
'SystemMemoryReporter.h',
|
||||
@ -119,16 +117,6 @@ UNIFIED_SOURCES += [
|
||||
'nsVersionComparatorImpl.cpp',
|
||||
]
|
||||
|
||||
# MOZ_STACKWALKING is defined in configure.in when the build configuration meets
|
||||
# the conditions for NS_StackWalk to work correctly.
|
||||
# We exclude this file from other build configurations so that if somebody adds a
|
||||
# new usage of NS_StackWalk it will cause a link error, which is better than having
|
||||
# NS_StackWalk silently return garbage at runtime.
|
||||
if CONFIG['MOZ_STACKWALKING']:
|
||||
SOURCES += [
|
||||
'nsStackWalk.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'Linux':
|
||||
SOURCES += [
|
||||
'LinuxUtils.cpp',
|
||||
|
@ -1,12 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Initialize the critical sections for this platform so that we can
|
||||
* abort stack walks when needed.
|
||||
*/
|
||||
void
|
||||
StackWalkInitCriticalAddress(void);
|
@ -18,8 +18,7 @@
|
||||
#include "nsCRT.h"
|
||||
#include <math.h>
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsStackWalkPrivate.h"
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "CodeAddressService.h"
|
||||
@ -238,7 +237,7 @@ struct CodeAddressServiceStringAlloc final
|
||||
static void free(char* aPtr) { ::free(aPtr); }
|
||||
};
|
||||
|
||||
// WalkTheStack does not hold any locks needed by NS_DescribeCodeAddress, so
|
||||
// WalkTheStack does not hold any locks needed by MozDescribeCodeAddress, so
|
||||
// this class does not need to do anything.
|
||||
struct CodeAddressServiceLock final
|
||||
{
|
||||
@ -837,11 +836,11 @@ static void
|
||||
PrintStackFrame(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
|
||||
{
|
||||
FILE* stream = (FILE*)aClosure;
|
||||
nsCodeAddressDetails details;
|
||||
MozCodeAddressDetails details;
|
||||
char buf[1024];
|
||||
|
||||
NS_DescribeCodeAddress(aPC, &details);
|
||||
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
|
||||
MozDescribeCodeAddress(aPC, &details);
|
||||
MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
|
||||
fprintf(stream, "%s\n", buf);
|
||||
fflush(stream);
|
||||
}
|
||||
@ -865,7 +864,7 @@ void
|
||||
nsTraceRefcnt::WalkTheStack(FILE* aStream)
|
||||
{
|
||||
#ifdef MOZ_STACKWALKING
|
||||
NS_StackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, aStream,
|
||||
MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, aStream,
|
||||
0, nullptr);
|
||||
#endif
|
||||
}
|
||||
@ -877,7 +876,7 @@ nsTraceRefcnt::WalkTheStackCached(FILE* aStream)
|
||||
if (!gCodeAddressService) {
|
||||
gCodeAddressService = new WalkTheStackCodeAddressService();
|
||||
}
|
||||
NS_StackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0,
|
||||
MozStackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0,
|
||||
aStream, 0, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#include "plstr.h"
|
||||
#include "prio.h"
|
||||
|
||||
@ -129,7 +129,7 @@ LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb)
|
||||
// concurrently from many writes, so we use multiple temporary files.
|
||||
std::vector<uintptr_t> rawStack;
|
||||
|
||||
NS_StackWalk(RecordStackWalker, /* skipFrames */ 0, /* maxFrames */ 0,
|
||||
MozStackWalk(RecordStackWalker, /* skipFrames */ 0, /* maxFrames */ 0,
|
||||
reinterpret_cast<void*>(&rawStack), 0, nullptr);
|
||||
Telemetry::ProcessedStack stack = Telemetry::GetStackAndModules(rawStack);
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "plstr.h"
|
||||
#include "prio.h"
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef MOZ_CALLSTACK_DISABLED
|
||||
#include "CodeAddressService.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#include "nsTHashtable.h"
|
||||
#endif
|
||||
|
||||
@ -68,7 +68,7 @@ BlockingResourceBase::GetStackTrace(AcquisitionState& aState)
|
||||
|
||||
// NB: Ignore the return value, there's nothing useful we can do if this
|
||||
// this fails.
|
||||
NS_StackWalk(StackWalkCallback, kSkipFrames, 24, &aState, 0, nullptr);
|
||||
MozStackWalk(StackWalkCallback, kSkipFrames, 24, &aState, 0, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
@ -146,7 +146,7 @@ GetChromeHangReport(Telemetry::ProcessedStack& aStack,
|
||||
if (ret == -1) {
|
||||
return;
|
||||
}
|
||||
NS_StackWalk(ChromeStackWalker, /* skipFrames */ 0, /* maxFrames */ 0,
|
||||
MozStackWalk(ChromeStackWalker, /* skipFrames */ 0, /* maxFrames */ 0,
|
||||
reinterpret_cast<void*>(&rawStack),
|
||||
reinterpret_cast<uintptr_t>(winMainThreadHandle), nullptr);
|
||||
ret = ::ResumeThread(winMainThreadHandle);
|
||||
|
@ -64,7 +64,7 @@
|
||||
|
||||
#if defined(NS_FUNCTION_TIMER) && defined(_MSC_VER)
|
||||
#include "nsTimerImpl.h"
|
||||
#include "nsStackWalk.h"
|
||||
#include "mozilla/StackWalk.h"
|
||||
#endif
|
||||
#ifdef NS_FUNCTION_TIMER
|
||||
#include "nsCRT.h"
|
||||
|
Loading…
Reference in New Issue
Block a user