author | Benoit Girard <b56girard@gmail.com> |
Wed, 10 Jun 2015 16:32:45 -0400 | |
changeset 249682 | d8c58dd8dabc156c3948a532d4bba47ccacb9977 |
parent 249681 | bf2f1318c3c052e9da173c32ed1dab4de2a4a30c |
child 249683 | d1d45ce7cbf53564f5549cf8cf8ce0eca2976cfd |
push id | 28936 |
push user | ryanvm@gmail.com |
push date | Fri, 19 Jun 2015 20:34:42 +0000 |
treeherder | mozilla-central@c319f262ce3e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | glandium |
bugs | 1172216 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/memory/replace/dmd/DMD.cpp +++ b/memory/replace/dmd/DMD.cpp @@ -22,17 +22,17 @@ #include <unistd.h> #endif #ifdef ANDROID #include <android/log.h> #endif #include "nscore.h" -#include "nsStackWalk.h" +#include "mozilla/StackWalk.h" #include "js/HashTable.h" #include "js/Vector.h" #include "mozilla/Assertions.h" #include "mozilla/HashFunctions.h" #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/JSONWriter.h" @@ -118,17 +118,17 @@ static bool gIsDMDInitialized = false; // This provides infallible allocations (they abort on OOM). We use it for all // of DMD's own allocations, which fall into the following three cases. // // - Direct allocations (the easy case). // // - 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, // but DMD cannot use mozalloc. // class InfallibleAllocPolicy { static void ExitOnFailure(const void* aP); @@ -507,17 +507,17 @@ static DMD_TLS_INDEX_TYPE gTlsIndex; class Thread { // Required for allocation via InfallibleAllocPolicy::new_. friend class InfallibleAllocPolicy; // 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() : mBlockIntercepts(false) {} DISALLOW_COPY_AND_ASSIGN(Thread); @@ -730,50 +730,33 @@ typedef js::HashMap<const void*, uint32_ static uint32_t gGCStackTraceTableWhenSizeExceeds = 4 * 1024; /* static */ const StackTrace* 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); if (!p) { StackTrace* stnew = InfallibleAllocPolicy::new_<StackTrace>(tmp); (void)gStackTraceTable->add(p, stnew); } return *p; @@ -1227,17 +1210,17 @@ replace_malloc(size_t aSize) // vanilla malloc. (In the latter case, if it fails we'll crash. But // OOM is highly unlikely so early on.) return gMallocTable->malloc(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); } // This must be a call to malloc from outside DMD. Intercept it. void* ptr = gMallocTable->malloc(aSize); AllocCallback(ptr, aSize, t); return ptr; } @@ -1550,19 +1533,19 @@ Init(const malloc_table_t* aMallocTable) // Parse $DMD env var. gOptions = InfallibleAllocPolicy::new_<Options>(e); #ifdef XP_MACOSX // On Mac OS X we need to call StackWalkInitCriticalAddress() very early // (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 gStateLock = InfallibleAllocPolicy::new_<Mutex>(); gSmallBlockActualSizeCounter = 0; DMD_CREATE_TLS_INDEX(gTlsIndex);
--- a/memory/replace/dmd/moz.build +++ b/memory/replace/dmd/moz.build @@ -8,17 +8,17 @@ FAIL_ON_WARNINGS = True EXPORTS += [ 'DMD.h', ] SOURCES += [ '../../../mfbt/HashFunctions.cpp', '../../../mfbt/JSONWriter.cpp', - '../../../xpcom/base/nsStackWalk.cpp', + '../../../mozglue/misc/StackWalk.cpp', 'DMD.cpp', ] SOURCES += [ '../../../nsprpub/lib/libc/src/strcpy.c', ] SharedLibrary('dmd')
rename from xpcom/base/nsStackWalk.cpp rename to mozglue/misc/StackWalk.cpp --- a/xpcom/base/nsStackWalk.cpp +++ b/mozglue/misc/StackWalk.cpp @@ -4,19 +4,16 @@ * 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++ stack on the current thread */ #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 #endif using namespace mozilla; // The presence of this address is the stack must stop the stack walk. If @@ -33,26 +30,26 @@ static CriticalAddress gCriticalAddress; #if defined(HAVE__UNWIND_BACKTRACE) && !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif #if defined(HAVE_DLOPEN) || defined(XP_DARWIN) #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 #include <CoreServices/CoreServices.h> #endif typedef void malloc_logger_t(uint32_t aType, @@ -105,28 +102,28 @@ my_malloc_logger(uint32_t aType, if (once) { return; } once = true; // 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); } // This is called from NS_LogInit() and from the stack walking functions, but // only the first call has any effect. We need to call this function from both // places because it must run before any mutexes are created, and also before // any objects whose refcounts we're logging are created. Running this // 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) { return; } gCriticalAddress.mInit = true; // We must not do work when 'new_sem_from_pool' calls realloc, since // it holds a non-reentrant spin-lock and we will quickly deadlock. @@ -176,34 +173,31 @@ IsCriticalAddress(void* aPC) static bool IsCriticalAddress(void* aPC) { return false; } // 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; } #endif #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. // A value of 9 indicates we want to use the new APIs. #if API_VERSION_NUMBER < 9 #error Too old imagehlp.h #endif @@ -507,29 +501,29 @@ WalkStackThread(void* aData) /** * Walk the stack, translating PC's found into strings and recording the * chain in aBuffer. For this to work properly, the DLLs must be rebased * so that the address in the file agrees with the address in memory. * Otherwise StackWalk will return FALSE when it hits a frame in a DLL * 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) { StackWalkInitCriticalAddress(); static HANDLE myProcess = nullptr; HANDLE myThread; DWORD walkerReturn; struct WalkStackData data; if (!EnsureWalkThreadReady()) { - return NS_ERROR_FAILURE; + return false; } HANDLE currentThread = ::GetCurrentThread(); HANDLE targetThread = aThread ? reinterpret_cast<HANDLE>(aThread) : currentThread; data.walkCallingThread = (targetThread == currentThread); // Have to duplicate handle to get a real handle. @@ -537,28 +531,28 @@ NS_StackWalk(NS_WalkStackCallback aCallb if (!::DuplicateHandle(::GetCurrentProcess(), ::GetCurrentProcess(), ::GetCurrentProcess(), &myProcess, PROCESS_ALL_ACCESS, FALSE, 0)) { if (data.walkCallingThread) { PrintError("DuplicateHandle (process)"); } - return NS_ERROR_FAILURE; + return false; } } if (!::DuplicateHandle(::GetCurrentProcess(), targetThread, ::GetCurrentProcess(), &myThread, THREAD_ALL_ACCESS, FALSE, 0)) { if (data.walkCallingThread) { PrintError("DuplicateHandle (thread)"); } - return NS_ERROR_FAILURE; + return false; } data.skipFrames = aSkipFrames; data.thread = myThread; data.process = myProcess; void* local_pcs[1024]; data.pcs = local_pcs; data.pc_count = 0; @@ -617,17 +611,17 @@ NS_StackWalk(NS_WalkStackCallback aCallb } ::CloseHandle(myThread); for (uint32_t i = 0; i < data.pc_count; ++i) { (*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; } static BOOL CALLBACK callbackEspecial64( PCSTR aModuleName, DWORD64 aModuleBase, ULONG aModuleSize, @@ -767,28 +761,28 @@ EnsureSymInitialized() gInitialized = retStat; /* XXX At some point we need to arrange to call SymCleanup */ return retStat; } -XPCOM_API(nsresult) -NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails) +MFBT_API bool +MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails) { aDetails->library[0] = '\0'; aDetails->loffset = 0; aDetails->filename[0] = '\0'; aDetails->lineno = 0; aDetails->function[0] = '\0'; aDetails->foffset = 0; if (!EnsureSymInitialized()) { - return NS_ERROR_FAILURE; + return false; } HANDLE myProcess = ::GetCurrentProcess(); BOOL ok; // debug routines are not threadsafe, so grab the lock. EnterCriticalSection(&gDbgHelpCS); @@ -799,54 +793,52 @@ NS_DescribeCodeAddress(void* aPC, nsCode DWORD64 addr = (DWORD64)aPC; IMAGEHLP_MODULE64 modInfo; IMAGEHLP_LINE64 lineInfo; BOOL modInfoRes; 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; } } ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; DWORD64 displacement; 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 // adherence thing. // #if (__GLIBC_MINOR__ >= 1) && !defined(__USE_GNU) #define __USE_GNU #endif @@ -863,34 +855,34 @@ void DemangleSymbol(const char* aSymbol, { aBuffer[0] = '\0'; #if defined(MOZ_DEMANGLE_SYMBOLS) /* See demangle.h in the gcc source for the voodoo */ 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 } #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) #define HAVE___LIBC_STACK_END 1 #else #define HAVE___LIBC_STACK_END 0 #endif #if HAVE___LIBC_STACK_END 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) { // Stack walking code courtesy Kipp's "leaky". int32_t skip = aSkipFrames; uint32_t numFrames = 0; while (1) { @@ -910,41 +902,41 @@ FramePointerStackWalk(NS_WalkStackCallba // ppc mac or powerpc64 linux void* pc = *(bp + 2); bp += 3; #else // i386 or powerpc32 linux void* pc = *(bp + 1); 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 // it called. We can't know the exact location of the SP // but this should be sufficient for our use the SP // to order elements on the stack. numFrames++; (*aCallback)(numFrames, pc, bp, aClosure); if (aMaxFrames != 0 && numFrames == aMaxFrames) { break; } } 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) { MOZ_ASSERT(!aThread); MOZ_ASSERT(!aPlatformData); StackWalkInitCriticalAddress(); // Get the frame pointer @@ -970,17 +962,17 @@ NS_StackWalk(NS_WalkStackCallback aCallb #elif defined(HAVE__UNWIND_BACKTRACE) // libgcc_s.so symbols _Unwind_Backtrace@@GCC_3.3 and _Unwind_GetIP@@GCC_3.0 #include <unwind.h> struct unwind_info { - NS_WalkStackCallback callback; + MozWalkStackCallback callback; int skip; int maxFrames; int numFrames; bool isCriticalAbort; void* closure; }; static _Unwind_Reason_Code @@ -1002,18 +994,18 @@ unwind_callback(struct _Unwind_Context* if (info->maxFrames != 0 && info->numFrames == info->maxFrames) { // Again, any error code that stops the walk will do. return _URC_FOREIGN_EXCEPTION_CAUGHT; } } 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) { MOZ_ASSERT(!aThread); MOZ_ASSERT(!aPlatformData); StackWalkInitCriticalAddress(); unwind_info info; info.callback = aCallback; @@ -1029,106 +1021,106 @@ NS_StackWalk(NS_WalkStackCallback aCallb // the outcome from |info|. There are two main reasons for this: // - On ARM/Android bionic's _Unwind_Backtrace usually (always?) returns // _URC_FAILURE. See // https://bugzilla.mozilla.org/show_bug.cgi?id=717853#c110. // - If aMaxFrames != 0, we want to stop early, and the only way to do that // 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; aDetails->filename[0] = '\0'; aDetails->lineno = 0; aDetails->function[0] = '\0'; aDetails->foffset = 0; 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; aDetails->filename[0] = '\0'; 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) { const char* function = aFunction && aFunction[0] ? aFunction : "???"; if (aFileName && aFileName[0]) { // We have a filename and (presumably) a line number. Use them. snprintf(aBuffer, aBufferSize,
rename from xpcom/base/nsStackWalk.h rename to mozglue/misc/StackWalk.h --- a/xpcom/base/nsStackWalk.h +++ b/mozglue/misc/StackWalk.h @@ -1,84 +1,67 @@ /* -*- 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++ 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. * @param aSP The best approximation possible of what the stack * 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. * Passing null causes us to walk the stack of the * current thread. On Windows, this is a thread HANDLE. * It is currently not supported on any other platform. * @param aPlatformData Platform specific data that can help in walking the * stack, this should be nullptr unless you really know * what you're doing! This needs to be a pointer to a * 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); typedef struct { /* * The name of the shared library or executable containing an * address and the address's offset within that library, or empty @@ -94,27 +77,27 @@ typedef struct char filename[256]; unsigned long lineno; /* * The name of the function containing an address and the address's * offset within that function, or empty string and zero if unknown. */ char function[256]; ptrdiff_t foffset; -} nsCodeAddressDetails; +} MozCodeAddressDetails; /** * For a given pointer to code, fill in the pieces of information used * when printing a stack trace. * * @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 * stack traces on the current platform. When available, this string * should contain the function name, source file, and line number. When * these are not available, library and offset should be reported, if * possible. * @@ -132,39 +115,51 @@ NS_DescribeCodeAddress(void* aPC, nsCode * @param aFrameNumber The frame number. * @param aPC The code address. * @param aFunction The function name. Possibly null or the empty string. * @param aLibrary The library name. Possibly null or the empty string. * @param aLOffset The library offset. * @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. * @param aBufferSize The size, in bytes, of aBuffer, including * room for the terminating null. If the information * to be printed would be larger than aBuffer, it * will be truncated so that aBuffer[aBufferSize-1] * 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 { -#ifdef __cplusplus +MFBT_API bool +FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames, + uint32_t aMaxFrames, void* aClosure, void** aBp, + void* aStackEnd); + } -#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
--- a/mozglue/misc/moz.build +++ b/mozglue/misc/moz.build @@ -1,11 +1,12 @@ FINAL_LIBRARY = 'mozglue' EXPORTS.mozilla += [ + 'StackWalk.h', 'TimeStamp.h', ] if CONFIG['OS_ARCH'] == 'WINNT': EXPORTS.mozilla += [ 'TimeStamp_windows.h', ] @@ -16,20 +17,31 @@ SOURCES += [ OS_LIBS += CONFIG['REALTIME_LIBS'] DEFINES['IMPL_MFBT'] = True if CONFIG['OS_ARCH'] == 'WINNT': SOURCES += [ 'TimeStamp_windows.cpp', ] + OS_LIBS += ['dbghelp'] elif CONFIG['HAVE_CLOCK_MONOTONIC']: SOURCES += [ 'TimeStamp_posix.cpp', ] elif CONFIG['OS_ARCH'] == 'Darwin': SOURCES += [ 'TimeStamp_darwin.cpp', ] 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
--- a/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h +++ b/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h @@ -13,17 +13,17 @@ #ifdef TARGET_SANDBOX_EXPORTS #include <sstream> #include <iostream> #include "mozilla/Preferences.h" #include "nsContentUtils.h" #ifdef MOZ_STACKWALKING -#include "nsStackWalk.h" +#include "mozilla/StackWalk.h" #endif #define TARGET_SANDBOX_EXPORT __declspec(dllexport) #else #define TARGET_SANDBOX_EXPORT __declspec(dllimport) #endif namespace mozilla { @@ -58,20 +58,20 @@ SetProvideLogFunctionCb(ProvideLogFuncti static uint32_t sStackTraceDepth = 0; // NS_WalkStackCallback to write a formatted stack frame to an ostringstream. static void 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(); } #endif // Log to the browser console and, if DEBUG build, stderr. static void Log(const char* aMessageType, @@ -85,17 +85,17 @@ Log(const char* aMessageType, if (aContext) { msgStream << " for : " << aContext; } #ifdef MOZ_STACKWALKING if (aShouldLogStackTrace) { if (sStackTraceDepth) { msgStream << std::endl << "Stack Trace:"; - NS_StackWalk(StackFrameToOStringStream, aFramesToSkip, sStackTraceDepth, + MozStackWalk(StackFrameToOStringStream, aFramesToSkip, sStackTraceDepth, &msgStream, 0, nullptr); } } #endif std::string msg = msgStream.str(); #if defined(DEBUG) // Use NS_DebugBreak directly as we want child process prefix, but not source
--- a/security/sandbox/linux/glue/SandboxCrash.cpp +++ b/security/sandbox/linux/glue/SandboxCrash.cpp @@ -16,17 +16,17 @@ #include <sys/syscall.h> #include "mozilla/unused.h" #include "mozilla/dom/Exceptions.h" #include "nsContentUtils.h" #ifdef MOZ_CRASHREPORTER #include "nsExceptionHandler.h" #endif -#include "nsStackWalk.h" +#include "mozilla/StackWalk.h" #include "nsString.h" #include "nsThreadUtils.h" namespace mozilla { // Log JS stack info in the same place as the sandbox violation // message. Useful in case the responsible code is JS and all we have // are logs and a minidump with the C++ stacks (e.g., on TBPL). @@ -72,34 +72,34 @@ SandboxLogJSStack(void) frame = nextFrame; } } 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); } static void 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."); } static void SandboxCrash(int nr, siginfo_t *info, void *void_context) { pid_t pid = getpid(), tid = syscall(__NR_gettid);
--- a/toolkit/xre/nsSigHandlers.cpp +++ b/toolkit/xre/nsSigHandlers.cpp @@ -51,48 +51,48 @@ static unsigned int _gdb_sleep_duration #ifndef PR_SET_PTRACER_ANY #define PR_SET_PTRACER_ANY ((unsigned long)-1) #endif #if defined(CRAWL_STACK_ON_SIGSEGV) #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 static const int kClientChannelFd = 3; extern "C" { 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); } } void ah_crap_handler(int signum) { printf("\nProgram %s (pid = %d) received signal %d.\n", _progname, getpid(), 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); printf("Type 'gdb %s %d' to attach your debugger to this thread.\n", _progname, getpid()); // Allow us to be ptraced by gdb on Linux with Yama restrictions enabled.
--- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -44,19 +44,16 @@ // JS #include "jsfriendapi.h" #include "js/ProfilingFrameIterator.h" #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; #elif defined(LINUX) #include <ucontext.h> typedef ucontext_t tickcontext_t; #endif @@ -875,47 +872,47 @@ void TableTicker::doNativeBacktrace(Thre NativeStack nativeStack = { pc_array, sp_array, mozilla::ArrayLength(pc_array), 0 }; // 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); uint32_t maxFrames = uint32_t(nativeStack.size - nativeStack.count); #ifdef XP_MACOSX pthread_t pt = GetProfiledThread(aSample->threadProfile->GetPlatformData()); 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, reinterpret_cast<void**>(aSample->fp), stackEnd); #else 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 #ifdef USE_EHABI_STACKWALK void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample) {
--- a/xpcom/base/CodeAddressService.h +++ b/xpcom/base/CodeAddressService.h @@ -8,41 +8,41 @@ #define CodeAddressService_h__ #include "mozilla/Assertions.h" #include "mozilla/HashFunctions.h" #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Types.h" -#include "nsStackWalk.h" +#include "mozilla/StackWalk.h" namespace mozilla { // This class is used to print details about code locations. // // |StringTable| must implement an Intern() method that returns an interned // copy of the string that was passed in, as well as a standard // SizeOfExcludingThis() method. // // |StringAlloc| must implement |copy| and |free|. |copy| copies a string, // 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, class DescribeCodeAddressLock> 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. // // - The number of distinct library names is small, e.g. a few dozen. There // is lots of repetition, especially of libxul. So we intern them in their // own table, which saves space over duplicating them for each cache entry. // @@ -132,39 +132,39 @@ public: uint32_t index = HashGeneric(aPc) & kMask; MOZ_ASSERT(index < kNumEntries); Entry& entry = mEntries[index]; 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(); } const char* library = mLibraryStrings.Intern(details.library); entry.Replace(aPc, details.function, library, details.loffset, details.filename, details.lineno); } else { mNumCacheHits++; } 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); } size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t n = aMallocSizeOf(this); for (uint32_t i = 0; i < kNumEntries; i++) {
deleted file mode 100644 --- a/xpcom/base/StackWalk.h +++ /dev/null @@ -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_) */
--- a/xpcom/base/moz.build +++ b/xpcom/base/moz.build @@ -51,17 +51,16 @@ EXPORTS += [ 'nsGZFileWriter.h', 'nsIID.h', 'nsInterfaceRequestorAgg.h', 'nsISizeOf.h', 'nsISupportsBase.h', 'nsObjCExceptions.h', 'nsQueryObject.h', 'nsRefPtr.h', - 'nsStackWalk.h', 'nsTraceRefcnt.h', 'nsWeakPtr.h', ] if CONFIG['OS_ARCH'] == 'WINNT': EXPORTS += [ 'nsWindowsHelpers.h', ] @@ -73,17 +72,16 @@ EXPORTS.mozilla += [ 'CycleCollectedJSRuntime.h', 'Debug.h', 'DebuggerOnGCRunnable.h', 'DeferredFinalize.h', 'ErrorNames.h', 'HoldDropJSObjects.h', 'LinuxUtils.h', 'nsMemoryInfoDumper.h', - 'StackWalk.h', 'StaticMutex.h', 'StaticPtr.h', 'SystemMemoryReporter.h', ] # nsDebugImpl isn't unified because we disable PGO so that NS_ABORT_OOM isn't # optimized away oddly. SOURCES += [ @@ -114,26 +112,16 @@ UNIFIED_SOURCES += [ 'nsSecurityConsoleMessage.cpp', 'nsStatusReporterManager.cpp', 'nsSystemInfo.cpp', 'nsTraceRefcnt.cpp', 'nsUUIDGenerator.cpp', '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', 'SystemMemoryReporter.cpp', ] if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': SOURCES += [
deleted file mode 100644 --- a/xpcom/base/nsStackWalkPrivate.h +++ /dev/null @@ -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);
--- a/xpcom/base/nsTraceRefcnt.cpp +++ b/xpcom/base/nsTraceRefcnt.cpp @@ -13,18 +13,17 @@ #include "nsTArray.h" #include "nsTHashtable.h" #include "prenv.h" #include "plstr.h" #include "prlink.h" #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" #include "nsXULAppAPI.h" #ifdef XP_WIN #include <process.h> #define getpid _getpid @@ -233,17 +232,17 @@ private: }; struct CodeAddressServiceStringAlloc final { static char* copy(const char* aStr) { return strdup(aStr); } 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 { static void Unlock() {} static void Lock() {} static bool IsLocked() { return true; } }; @@ -832,21 +831,21 @@ InitTraceLog() extern "C" { #ifdef MOZ_STACKWALKING 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); } static void PrintStackFrameCached(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure) { @@ -860,29 +859,29 @@ PrintStackFrameCached(uint32_t aFrameNum #endif } 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 } void nsTraceRefcnt::WalkTheStackCached(FILE* aStream) { #ifdef MOZ_STACKWALKING if (!gCodeAddressService) { gCodeAddressService = new WalkTheStackCodeAddressService(); } - NS_StackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0, + MozStackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0, aStream, 0, nullptr); #endif } //---------------------------------------------------------------------- // This thing is exported by libstdc++ // Yes, this is a gcc only hack
--- a/xpcom/build/LateWriteChecks.cpp +++ b/xpcom/build/LateWriteChecks.cpp @@ -11,17 +11,17 @@ #include "mozilla/ProcessedStack.h" #include "mozilla/SHA1.h" #include "mozilla/Scoped.h" #include "mozilla/StaticPtr.h" #include "mozilla/Telemetry.h" #include "nsAppDirectoryServiceDefs.h" #include "nsDirectoryServiceUtils.h" #include "nsPrintfCString.h" -#include "nsStackWalk.h" +#include "mozilla/StackWalk.h" #include "plstr.h" #include "prio.h" #ifdef XP_WIN #define NS_T(str) L ## str #define NS_SLASH "\\" #include <fcntl.h> #include <io.h> @@ -124,17 +124,17 @@ LateWriteObserver::Observe(IOInterposeOb if (gShutdownChecks == SCM_NOTHING || !Telemetry::CanRecordExtended()) { return; } // Write the stack and loaded libraries to a file. We can get here // 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); nsPrintfCString nameAux("%s%s%s", mProfileDirectory, NS_SLASH, "Telemetry.LateWriteTmpXXXXXX"); char* name; nameAux.GetMutableData(&name);
--- a/xpcom/build/PoisonIOInterposerMac.cpp +++ b/xpcom/build/PoisonIOInterposerMac.cpp @@ -11,17 +11,17 @@ #include "mozilla/Assertions.h" #include "mozilla/DebugOnly.h" #include "mozilla/IOInterposer.h" #include "mozilla/Mutex.h" #include "mozilla/ProcessedStack.h" #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" #include <algorithm> #include <vector> #include <sys/param.h>
--- a/xpcom/glue/BlockingResourceBase.cpp +++ b/xpcom/glue/BlockingResourceBase.cpp @@ -9,17 +9,17 @@ #ifdef DEBUG #include "prthread.h" #include "nsAutoPtr.h" #ifndef MOZ_CALLSTACK_DISABLED #include "CodeAddressService.h" #include "nsHashKeys.h" -#include "nsStackWalk.h" +#include "mozilla/StackWalk.h" #include "nsTHashtable.h" #endif #include "mozilla/CondVar.h" #include "mozilla/DeadlockDetector.h" #include "mozilla/ReentrantMonitor.h" #include "mozilla/Mutex.h" @@ -63,17 +63,17 @@ BlockingResourceBase::GetStackTrace(Acqu #ifndef MOZ_CALLSTACK_DISABLED // Skip this function and the calling function. const uint32_t kSkipFrames = 2; aState.Clear(); // 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 } /** * PrintCycle * Append to |aOut| detailed information about the circular * dependency in |aCycle|. Returns true if it *appears* that this * cycle may represent an imminent deadlock, but this is merely a
--- a/xpcom/threads/HangMonitor.cpp +++ b/xpcom/threads/HangMonitor.cpp @@ -10,17 +10,17 @@ #include "mozilla/BackgroundHangMonitor.h" #include "mozilla/Monitor.h" #include "mozilla/Preferences.h" #include "mozilla/ProcessedStack.h" #include "mozilla/Telemetry.h" #include "mozilla/StaticPtr.h" #include "mozilla/UniquePtr.h" #include "nsReadableUtils.h" -#include "nsStackWalk.h" +#include "mozilla/StackWalk.h" #include "nsThreadUtils.h" #include "nsXULAppAPI.h" #ifdef MOZ_CRASHREPORTER #include "nsExceptionHandler.h" #endif #ifdef XP_WIN @@ -141,17 +141,17 @@ GetChromeHangReport(Telemetry::Processed // The thread we're about to suspend might have the alloc lock // so allocate ahead of time std::vector<uintptr_t> rawStack; rawStack.reserve(MAX_CALL_STACK_PCS); DWORD ret = ::SuspendThread(winMainThreadHandle); 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); if (ret == -1) { return; } aStack = Telemetry::GetStackAndModules(rawStack);
--- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -59,17 +59,17 @@ # include <execinfo.h> # include <signal.h> # include <fcntl.h> # include "nsXULAppAPI.h" #endif #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" #endif #ifdef MOZ_TASK_TRACER #include "GeckoTaskTracer.h" #include "TracedTaskCommon.h"