Backed out 3 changesets (bug 1322735) for ASan leaks and xpcshell/selftest.py failures
authorPhil Ringnalda <philringnalda@gmail.com>
Tue, 10 Jan 2017 20:17:34 -0800
changeset 376095 90f03368f795213ff5af22d2f3e2712e7a015c05
parent 376094 01cfc71ce54263d18c5fa4b9f4314aae8a8e16ff
child 376096 f3f50b7726800e4470d5385ea2249b1af62bee63
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1322735
milestone53.0a1
backs out01cfc71ce54263d18c5fa4b9f4314aae8a8e16ff
84c729c41230510b59ec323a4acbeb5911ca7389
b419aaefae9553e2dfd6d634c62a5c5721bc0923
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
Backed out 3 changesets (bug 1322735) for ASan leaks and xpcshell/selftest.py failures CLOSED TREE Backed out changeset 01cfc71ce542 (bug 1322735) Backed out changeset 84c729c41230 (bug 1322735) Backed out changeset b419aaefae95 (bug 1322735)
browser/app/profile/firefox.js
build/autoconf/frameptr.m4
js/src/jit/ExecutableAllocatorWin.cpp
js/src/old-configure.in
mozglue/misc/StackWalk.h
mozglue/misc/moz.build
old-configure.in
security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/tests/unit/test_TelemetryCaptureStack.js
toolkit/modules/AppConstants.jsm
tools/profiler/core/platform-win32.cc
xpcom/base/nsTraceRefcnt.cpp
xpcom/build/LateWriteChecks.cpp
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -956,23 +956,25 @@ pref("dom.ipc.plugins.sandbox-level.flas
 // See - security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
 // SetSecurityLevelForContentProcess() for what the different settings mean.
 #if defined(NIGHTLY_BUILD)
 pref("security.sandbox.content.level", 2);
 #else
 pref("security.sandbox.content.level", 1);
 #endif
 
+#if defined(MOZ_STACKWALKING)
 // This controls the depth of stack trace that is logged when Windows sandbox
 // logging is turned on.  This is only currently available for the content
 // process because the only other sandbox (for GMP) has too strict a policy to
 // allow stack tracing.  This does not require a restart to take effect.
 pref("security.sandbox.windows.log.stackTraceDepth", 0);
 #endif
 #endif
+#endif
 
 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
 // This pref is discussed in bug 1083344, the naming is inspired from its
 // Windows counterpart, but on Mac it's an integer which means:
 // 0 -> "no sandbox"
 // 1 -> "preliminary content sandboxing enabled: write access to
 //       home directory is prevented"
 // 2 -> "preliminary content sandboxing enabled with profile protection:
--- a/build/autoconf/frameptr.m4
+++ b/build/autoconf/frameptr.m4
@@ -24,21 +24,19 @@ AC_DEFUN([MOZ_SET_FRAMEPTR_FLAGS], [
     dnl Oy (Frame-Pointer Omission) is only support on x86 compilers
     *-mingw32*)
       MOZ_ENABLE_FRAME_PTR="-Oy-"
       MOZ_DISABLE_FRAME_PTR="-Oy"
     ;;
     esac
   fi
 
-  # If we are debugging, profiling, using sanitizers, or on win32 we want a
-  # frame pointer.
+  # if we are debugging, profiling or using sanitizers, we want a frame pointer.
   if test -z "$MOZ_OPTIMIZE" -o \
           -n "$MOZ_PROFILING" -o \
           -n "$MOZ_DEBUG" -o \
           -n "$MOZ_MSAN" -o \
-          -n "$MOZ_ASAN" -o
-          "$OS_ARCH:$CPU_ARCH" = "WINNT:x86"; then
+          -n "$MOZ_ASAN"; then
     MOZ_FRAMEPTR_FLAGS="$MOZ_ENABLE_FRAME_PTR"
   else
     MOZ_FRAMEPTR_FLAGS="$MOZ_DISABLE_FRAME_PTR"
   fi
 ])
--- a/js/src/jit/ExecutableAllocatorWin.cpp
+++ b/js/src/jit/ExecutableAllocatorWin.cpp
@@ -20,17 +20,19 @@
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifdef MOZ_STACKWALKING
 #include "mozilla/StackWalk_windows.h"
+#endif
 
 #include "mozilla/WindowsVersion.h"
 
 #include "jsfriendapi.h"
 #include "jsmath.h"
 #include "jswin.h"
 
 #include "jit/ExecutableAllocator.h"
@@ -164,37 +166,45 @@ RegisterExecutableMemory(void* p, size_t
     r->thunk[10] = 0xff;
     r->thunk[11] = 0xe0;
 
     if (!VirtualProtect(p, pageSize, PAGE_EXECUTE_READ, &oldProtect))
         return false;
 
     // XXX NB: The profiler believes this function is only called from the main
     // thread. If that ever becomes untrue, SPS must be updated immediately.
+#ifdef MOZ_STACKWALKING
     AcquireStackWalkWorkaroundLock();
+#endif
 
     bool success = RtlAddFunctionTable(&r->runtimeFunction, 1, reinterpret_cast<DWORD64>(p));
 
+#ifdef MOZ_STACKWALKING
     ReleaseStackWalkWorkaroundLock();
+#endif
 
     return success;
 }
 
 static void
 UnregisterExecutableMemory(void* p, size_t bytes, size_t pageSize)
 {
     ExceptionHandlerRecord* r = reinterpret_cast<ExceptionHandlerRecord*>(p);
 
     // XXX NB: The profiler believes this function is only called from the main
     // thread. If that ever becomes untrue, SPS must be updated immediately.
+#ifdef MOZ_STACKWALKING
     AcquireStackWalkWorkaroundLock();
+#endif
 
     RtlDeleteFunctionTable(&r->runtimeFunction);
 
+#ifdef MOZ_STACKWALKING
     ReleaseStackWalkWorkaroundLock();
+#endif
 }
 #endif
 
 void*
 js::jit::AllocateExecutableMemory(void* addr, size_t bytes, unsigned permissions, const char* tag,
                                   size_t pageSize)
 {
     MOZ_ASSERT(bytes % pageSize == 0);
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -1507,16 +1507,43 @@ fi # COMPILE_ENVIRONMENT
 
 AC_SUBST(MOZ_OPTIMIZE)
 AC_SUBST(MOZ_FRAMEPTR_FLAGS)
 AC_SUBST(MOZ_OPTIMIZE_FLAGS)
 AC_SUBST(MOZ_OPTIMIZE_LDFLAGS)
 AC_SUBST(MOZ_PGO_OPTIMIZE_FLAGS)
 
 dnl ========================================================
+dnl = Enable NS_StackWalk.
+dnl ========================================================
+
+# On Windows, NS_StackWalk will only work correctly if we have frame pointers
+# available. That will only be true for non-optimized builds, debug builds or
+# builds with --enable-profiling in the .mozconfig (which is turned on in
+# Nightly by default.)
+case "$OS_TARGET" in
+WINNT)
+    if test -z "$MOZ_OPTIMIZE" -o -n "$MOZ_PROFILING" -o -n "$MOZ_DEBUG"; then
+        MOZ_STACKWALKING=1
+    else
+        MOZ_STACKWALKING=
+    fi
+    ;;
+*)
+    MOZ_STACKWALKING=1
+    ;;
+esac
+
+if test -n "$MOZ_STACKWALKING"; then
+    AC_DEFINE(MOZ_STACKWALKING)
+fi
+
+AC_SUBST(MOZ_STACKWALKING)
+
+dnl ========================================================
 dnl = Disable trace logging
 dnl ========================================================
 ENABLE_TRACE_LOGGING=1
 MOZ_ARG_DISABLE_BOOL(trace-logging,
 [  --disable-trace-logging   Disable trace logging],
     ENABLE_TRACE_LOGGING= )
 
 AC_SUBST(ENABLE_TRACE_LOGGING)
--- a/mozglue/misc/StackWalk.h
+++ b/mozglue/misc/StackWalk.h
@@ -47,16 +47,18 @@ typedef void
  *                      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.
  *
  * 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.
  */
 MFBT_API bool
 MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
              uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
              void* aPlatformData);
 
 typedef struct
 {
--- a/mozglue/misc/moz.build
+++ b/mozglue/misc/moz.build
@@ -7,17 +7,16 @@ EXPORTS.mozilla += [
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS.mozilla += [
         'StackWalk_windows.h',
         'TimeStamp_windows.h',
     ]
 
 SOURCES += [
-    'StackWalk.cpp',
     'TimeStamp.cpp',
 ]
 
 OS_LIBS += CONFIG['REALTIME_LIBS']
 
 DEFINES['IMPL_MFBT'] = True
 
 if CONFIG['OS_ARCH'] == 'WINNT':
@@ -30,8 +29,18 @@ elif CONFIG['HAVE_CLOCK_MONOTONIC']:
         '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',
+    ]
--- a/old-configure.in
+++ b/old-configure.in
@@ -4152,16 +4152,43 @@ fi # COMPILE_ENVIRONMENT
 
 AC_SUBST(MOZ_OPTIMIZE)
 AC_SUBST(MOZ_FRAMEPTR_FLAGS)
 AC_SUBST(MOZ_OPTIMIZE_FLAGS)
 AC_SUBST(MOZ_OPTIMIZE_LDFLAGS)
 AC_SUBST(MOZ_PGO_OPTIMIZE_FLAGS)
 
 dnl ========================================================
+dnl = Enable NS_StackWalk.
+dnl ========================================================
+
+# On Windows, NS_StackWalk will only work correctly if we have frame pointers
+# available. That will only be true for non-optimized builds, debug builds or
+# builds with --enable-profiling in the .mozconfig (which is turned on in
+# Nightly by default.)
+case "$OS_TARGET" in
+WINNT)
+    if test -z "$MOZ_OPTIMIZE" -o -n "$MOZ_PROFILING" -o -n "$MOZ_DEBUG"; then
+        MOZ_STACKWALKING=1
+    else
+        MOZ_STACKWALKING=
+    fi
+    ;;
+*)
+    MOZ_STACKWALKING=1
+    ;;
+esac
+
+if test -n "$MOZ_STACKWALKING"; then
+    AC_DEFINE(MOZ_STACKWALKING)
+fi
+
+AC_SUBST(MOZ_STACKWALKING)
+
+dnl ========================================================
 dnl = Disable treating compiler warnings as errors
 dnl ========================================================
 if test -z "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
    WARNINGS_AS_ERRORS=''
 fi
 
 dnl ========================================================
 dnl = Enable runtime logging
--- a/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
+++ b/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
@@ -10,63 +10,69 @@
 #include <sstream>
 #include <iostream>
 
 #include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/sandboxing/loggingTypes.h"
 #include "nsContentUtils.h"
 
+#ifdef MOZ_STACKWALKING
 #include "mozilla/StackWalk.h"
+#endif
 
 namespace mozilla {
 
 static LazyLogModule sSandboxTargetLog("SandboxTarget");
 
 #define LOG_D(...) MOZ_LOG(sSandboxTargetLog, LogLevel::Debug, (__VA_ARGS__))
 
 namespace sandboxing {
 
+#ifdef MOZ_STACKWALKING
 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);
   MozCodeAddressDetails details;
   char buf[1024];
   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,
     const char* aFunctionName,
     const char* aContext,
     const bool aShouldLogStackTrace = false,
     uint32_t aFramesToSkip = 0)
 {
   std::ostringstream msgStream;
   msgStream << "Process Sandbox " << aMessageType << ": " << aFunctionName;
   if (aContext) {
     msgStream << " for : " << aContext;
   }
 
+#ifdef MOZ_STACKWALKING
   if (aShouldLogStackTrace) {
     if (sStackTraceDepth) {
       msgStream << std::endl << "Stack Trace:";
       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
   // file or line number.
   NS_DebugBreak(NS_DEBUG_WARNING, nullptr, msg.c_str(), nullptr, -1);
 #endif
 
@@ -85,17 +91,17 @@ InitLoggingIfRequired(ProvideLogFunction
   if (!aProvideLogFunctionCb) {
     return;
   }
 
   if (Preferences::GetBool("security.sandbox.windows.log") ||
       PR_GetEnv("MOZ_WIN_SANDBOX_LOGGING")) {
     aProvideLogFunctionCb(Log);
 
-#if defined(MOZ_CONTENT_SANDBOX)
+#if defined(MOZ_CONTENT_SANDBOX) && defined(MOZ_STACKWALKING)
     // We can only log the stack trace on process types where we know that the
     // sandbox won't prevent it.
     if (XRE_IsContentProcess()) {
       Preferences::AddUintVarCache(&sStackTraceDepth,
         "security.sandbox.windows.log.stackTraceDepth");
     }
 #endif
   }
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -71,19 +71,21 @@
 #include "mozilla/StaticPtr.h"
 #include "mozilla/IOInterposer.h"
 #include "mozilla/PoisonIOInterposer.h"
 #include "mozilla/StartupTimeline.h"
 #include "mozilla/HangMonitor.h"
 
 #if defined(MOZ_ENABLE_PROFILER_SPS)
 #include "shared-libraries.h"
+#if defined(MOZ_STACKWALKING)
 #define ENABLE_STACK_CAPTURE
 #include "mozilla/StackWalk.h"
 #include "nsPrintfCString.h"
+#endif // MOZ_STACKWALKING
 #endif // MOZ_ENABLE_PROFILER_SPS
 
 namespace {
 
 using namespace mozilla;
 using namespace mozilla::HangMonitor;
 using Telemetry::Common::AutoHashtable;
 
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryCaptureStack.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryCaptureStack.js
@@ -1,16 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 Cu.import("resource://gre/modules/TelemetryController.jsm", this);
 Cu.import("resource://gre/modules/AppConstants.jsm", this);
 
 // We need both in order to capture stacks.
-const ENABLE_TESTS = AppConstants.MOZ_ENABLE_PROFILER_SPS;
+const ENABLE_TESTS = AppConstants.MOZ_ENABLE_PROFILER_SPS &&
+                     AppConstants.MOZ_STACKWALKING;
 
 /**
  * Ensures that the sctucture of the javascript object used for capturing stacks
  * is as intended. The structure is expected to be as in this example:
  *
  * {
  *  "memoryMap": [
  *      [String, String],
--- a/toolkit/modules/AppConstants.jsm
+++ b/toolkit/modules/AppConstants.jsm
@@ -290,16 +290,23 @@ this.AppConstants = Object.freeze({
 
   MOZ_ENABLE_PROFILER_SPS:
 #ifdef MOZ_ENABLE_PROFILER_SPS
   true,
 #else
   false,
 #endif
 
+  MOZ_STACKWALKING:
+#ifdef MOZ_STACKWALKING
+  true,
+#else
+  false,
+#endif
+
   MOZ_ANDROID_ACTIVITY_STREAM:
 #ifdef MOZ_ANDROID_ACTIVITY_STREAM
   true,
 #else
   false,
 #endif
 
   DLL_PREFIX: "@DLL_PREFIX@",
--- a/tools/profiler/core/platform-win32.cc
+++ b/tools/profiler/core/platform-win32.cc
@@ -32,17 +32,19 @@
 #include "platform.h"
 #include "GeckoSampler.h"
 #include "ThreadResponsiveness.h"
 #include "ProfileEntry.h"
 
 // Memory profile
 #include "nsMemoryReporterManager.h"
 
+#ifdef MOZ_STACKWALKING
 #include "mozilla/StackWalk_windows.h"
+#endif
 
 
 class PlatformData {
  public:
   // Get a handle to the calling thread. This is the thread that we are
   // going to profile. We need to make a copy of the handle because we are
   // going to use it in the sampler thread. Using GetThreadHandle() will
   // not work in this case. We're using OpenThread because DuplicateHandle
@@ -203,16 +205,17 @@ class SamplerThread : public Thread {
 #else
     context.ContextFlags = CONTEXT_CONTROL;
 #endif
     if (!GetThreadContext(profiled_thread, &context)) {
       ResumeThread(profiled_thread);
       return;
     }
 
+#ifdef MOZ_STACKWALKING
     // Threads that may invoke JS require extra attention. Since, on windows,
     // the jits also need to modify the same dynamic function table that we need
     // to get a stack trace, we have to be wary of that to avoid deadlock.
     //
     // When embedded in Gecko, for threads that aren't the main thread,
     // CanInvokeJS consults an unlocked value in the nsIThread, so we must
     // consult this after suspending the profiled thread to avoid racing
     // against a value change.
@@ -225,16 +228,17 @@ class SamplerThread : public Thread {
       // It is safe to immediately drop the lock. We only need to contend with
       // the case in which the profiled thread held needed system resources.
       // If the profiled thread had held those resources, the trylock would have
       // failed. Anyone else who grabs those resources will continue to make
       // progress, since those threads are not suspended. Because of this,
       // we cannot deadlock with them, and should let them run as they please.
       ReleaseStackWalkWorkaroundLock();
     }
+#endif
 
 #if V8_HOST_ARCH_X64
     sample->pc = reinterpret_cast<Address>(context.Rip);
     sample->sp = reinterpret_cast<Address>(context.Rsp);
     sample->fp = reinterpret_cast<Address>(context.Rbp);
 #else
     sample->pc = reinterpret_cast<Address>(context.Eip);
     sample->sp = reinterpret_cast<Address>(context.Esp);
--- a/xpcom/base/nsTraceRefcnt.cpp
+++ b/xpcom/base/nsTraceRefcnt.cpp
@@ -228,16 +228,18 @@ static const PLHashAllocOps serialNumber
 
 static const PLHashAllocOps typesToLogHashAllocOps = {
   DefaultAllocTable, DefaultFreeTable,
   DefaultAllocEntry, TypesToLogFreeEntry
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
+#ifdef MOZ_STACKWALKING
+
 class CodeAddressServiceStringTable final
 {
 public:
   CodeAddressServiceStringTable() : mSet(32) {}
 
   const char* Intern(const char* aString)
   {
     nsCharPtrHashKey* e = mSet.PutEntry(aString);
@@ -270,16 +272,18 @@ struct CodeAddressServiceLock final
 };
 
 typedef mozilla::CodeAddressService<CodeAddressServiceStringTable,
                                     CodeAddressServiceStringAlloc,
                                     CodeAddressServiceLock> WalkTheStackCodeAddressService;
 
 mozilla::StaticAutoPtr<WalkTheStackCodeAddressService> gCodeAddressService;
 
+#endif // MOZ_STACKWALKING
+
 ////////////////////////////////////////////////////////////////////////////////
 
 class BloatEntry
 {
 public:
   BloatEntry(const char* aClassName, uint32_t aClassSize)
     : mClassSize(aClassSize)
   {
@@ -455,28 +459,30 @@ DumpSerialNumbers(PLHashEntry* aHashEntr
           record->COMPtrCount);
 #else
   fprintf(outputFile, "%" PRIdPTR
           " @%p (%d references)\n",
           record->serialNumber,
           aHashEntry->key,
           record->refCount);
 #endif
+#ifdef MOZ_STACKWALKING
   if (!record->allocationStack.empty()) {
     static const size_t bufLen = 1024;
     char buf[bufLen];
     fprintf(outputFile, "allocation stack:\n");
     for (size_t i = 0, length = record->allocationStack.size();
          i < length;
          ++i) {
       gCodeAddressService->GetLocation(i, record->allocationStack[i],
                                        buf, bufLen);
       fprintf(outputFile, "%s\n", buf);
     }
   }
+#endif
   return HT_ENUMERATE_NEXT;
 }
 
 
 template<>
 class nsDefaultComparator<BloatEntry*, BloatEntry*>
 {
 public:
@@ -837,16 +843,17 @@ InitTraceLog()
   if (gRefcntsLog || gAllocLog || gCOMPtrLog) {
     gLogging = FullLogging;
   }
 }
 
 
 extern "C" {
 
+#ifdef MOZ_STACKWALKING
 static void
 PrintStackFrame(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
 {
   FILE* stream = (FILE*)aClosure;
   MozCodeAddressDetails details;
   char buf[1024];
 
   MozDescribeCodeAddress(aPC, &details);
@@ -869,67 +876,76 @@ PrintStackFrameCached(uint32_t aFrameNum
 
 static void
 RecordStackFrame(uint32_t /*aFrameNumber*/, void* aPC, void* /*aSP*/,
                  void* aClosure)
 {
   auto locations = static_cast<std::vector<void*>*>(aClosure);
   locations->push_back(aPC);
 }
+#endif // MOZ_STACKWALKING
 
 }
 
 void
 nsTraceRefcnt::WalkTheStack(FILE* aStream)
 {
+#ifdef MOZ_STACKWALKING
   MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, aStream,
                0, nullptr);
+#endif
 }
 
 /**
  * This is a variant of |WalkTheStack| that uses |CodeAddressService| to cache
  * the results of |NS_DescribeCodeAddress|. If |WalkTheStackCached| is being
  * called frequently, it will be a few orders of magnitude faster than
  * |WalkTheStack|. However, the cache uses a lot of memory, which can cause
  * OOM crashes. Therefore, this should only be used for things like refcount
  * logging which walk the stack extremely frequently.
  */
 static void
 WalkTheStackCached(FILE* aStream)
 {
+#ifdef MOZ_STACKWALKING
   if (!gCodeAddressService) {
     gCodeAddressService = new WalkTheStackCodeAddressService();
   }
   MozStackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0,
                aStream, 0, nullptr);
+#endif
 }
 
 static void
 WalkTheStackSavingLocations(std::vector<void*>& aLocations)
 {
+#ifdef MOZ_STACKWALKING
   if (!gCodeAddressService) {
     gCodeAddressService = new WalkTheStackCodeAddressService();
   }
   static const int kFramesToSkip =
     0 +                         // this frame gets inlined
     1 +                         // GetSerialNumber
     1;                          // NS_LogCtor
   MozStackWalk(RecordStackFrame, kFramesToSkip, /* maxFrames */ 0,
                &aLocations, 0, nullptr);
+#endif
 }
 
 //----------------------------------------------------------------------
 
 EXPORT_XPCOM_API(void)
 NS_LogInit()
 {
   NS_SetMainThread();
 
   // FIXME: This is called multiple times, we should probably not allow that.
+#ifdef MOZ_STACKWALKING
   StackWalkInitCriticalAddress();
+#endif
   if (++gInitCount) {
     nsTraceRefcnt::SetActivityIsLegal(true);
   }
 }
 
 EXPORT_XPCOM_API(void)
 NS_LogTerm()
 {
@@ -1280,17 +1296,19 @@ NS_LogCOMPtrRelease(void* aCOMPtr, nsISu
     }
   }
 #endif // HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR
 }
 
 void
 nsTraceRefcnt::Shutdown()
 {
+#ifdef MOZ_STACKWALKING
   gCodeAddressService = nullptr;
+#endif
   if (gBloatView) {
     PL_HashTableDestroy(gBloatView);
     gBloatView = nullptr;
   }
   if (gTypesToLog) {
     PL_HashTableDestroy(gTypesToLog);
     gTypesToLog = nullptr;
   }
--- a/xpcom/build/LateWriteChecks.cpp
+++ b/xpcom/build/LateWriteChecks.cpp
@@ -30,16 +30,20 @@
 #include <sys/stat.h>
 #include <windows.h>
 #else
 #define NS_SLASH "/"
 #endif
 
 #include "LateWriteChecks.h"
 
+#if defined(MOZ_STACKWALKING)
+#define OBSERVE_LATE_WRITES
+#endif
+
 using namespace mozilla;
 
 /*************************** Auxiliary Declarations ***************************/
 
 // This a wrapper over a file descriptor that provides a Printf method and
 // computes the sha1 of the data that passes through it.
 class SHA1Stream
 {
@@ -105,16 +109,17 @@ public:
   void Observe(IOInterposeObserver::Observation& aObservation);
 private:
   char* mProfileDirectory;
 };
 
 void
 LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb)
 {
+#ifdef OBSERVE_LATE_WRITES
   // Crash if that is the shutdown check mode
   if (gShutdownChecks == SCM_CRASH) {
     MOZ_CRASH();
   }
 
   // If we have shutdown mode SCM_NOTHING or we can't record then abort
   if (gShutdownChecks == SCM_NOTHING || !Telemetry::CanRecordExtended()) {
     return;
@@ -199,16 +204,17 @@ LateWriteObserver::Observe(IOInterposeOb
   // client side deduplication.
   nsPrintfCString finalName("%s%s", mProfileDirectory,
                             "/Telemetry.LateWriteFinal-");
   for (int i = 0; i < 20; ++i) {
     finalName.AppendPrintf("%02x", sha1[i]);
   }
   PR_Delete(finalName.get());
   PR_Rename(name, finalName.get());
+#endif
 }
 
 /******************************* Setup/Teardown *******************************/
 
 static StaticAutoPtr<LateWriteObserver> sLateWriteObserver;
 
 namespace mozilla {