Bug 1172216 - Move nsStackwalk to mozglue. r=glandium
authorBenoit Girard <b56girard@gmail.com>
Wed, 10 Jun 2015 16:32:45 -0400
changeset 267775 d8c58dd8dabc156c3948a532d4bba47ccacb9977
parent 267774 bf2f1318c3c052e9da173c32ed1dab4de2a4a30c
child 267776 d1d45ce7cbf53564f5549cf8cf8ce0eca2976cfd
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1172216
milestone41.0a1
Bug 1172216 - Move nsStackwalk to mozglue. r=glandium
memory/replace/dmd/DMD.cpp
memory/replace/dmd/moz.build
mozglue/misc/StackWalk.cpp
mozglue/misc/StackWalk.h
mozglue/misc/moz.build
security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
security/sandbox/linux/glue/SandboxCrash.cpp
toolkit/xre/nsSigHandlers.cpp
tools/profiler/TableTicker.cpp
xpcom/base/CodeAddressService.h
xpcom/base/StackWalk.h
xpcom/base/moz.build
xpcom/base/nsStackWalk.cpp
xpcom/base/nsStackWalk.h
xpcom/base/nsStackWalkPrivate.h
xpcom/base/nsTraceRefcnt.cpp
xpcom/build/LateWriteChecks.cpp
xpcom/build/PoisonIOInterposerMac.cpp
xpcom/glue/BlockingResourceBase.cpp
xpcom/threads/HangMonitor.cpp
xpcom/threads/nsThread.cpp
--- 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"