Bug 1172216 - Move nsStackwalk to mozglue. r=glandium
authorBenoit Girard <b56girard@gmail.com>
Wed, 10 Jun 2015 16:32:45 -0400
changeset 249682 d8c58dd8dabc156c3948a532d4bba47ccacb9977
parent 249681 bf2f1318c3c052e9da173c32ed1dab4de2a4a30c
child 249683 d1d45ce7cbf53564f5549cf8cf8ce0eca2976cfd
push id28936
push userryanvm@gmail.com
push dateFri, 19 Jun 2015 20:34:42 +0000
treeherdermozilla-central@c319f262ce3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1172216
milestone41.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
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"