Backed out changeset 7a1b7d7eba12 (bug 1062709)
authorEd Morley <emorley@mozilla.com>
Fri, 03 Oct 2014 15:05:26 +0100
changeset 219846 c0f5f5f80e66c384020356de6d64c70d72fb1587
parent 219845 84204f7936028d2e78b670b001aa79d8eda922f0
child 219847 388e101e75c826f64aa3fb0de4b7fcf1faadcbbf
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-esr52@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1062709
milestone35.0a1
backs out7a1b7d7eba12c1f68ccd74a2c3ed7ea2a9e48a75
Backed out changeset 7a1b7d7eba12 (bug 1062709)
security/sandbox/win/src/warnonlysandbox/wosCallbacks.h
toolkit/xre/nsSigHandlers.cpp
tools/rb/fix_linux_stack.py
tools/rb/fix_macosx_stack.py
tools/rb/fix_stack_using_bpsyms.py
tools/rb/make-tree.pl
xpcom/base/CodeAddressService.h
xpcom/base/nsStackWalk.cpp
xpcom/base/nsStackWalk.h
xpcom/base/nsTraceRefcnt.cpp
xpcom/glue/BlockingResourceBase.cpp
--- a/security/sandbox/win/src/warnonlysandbox/wosCallbacks.h
+++ b/security/sandbox/win/src/warnonlysandbox/wosCallbacks.h
@@ -61,18 +61,18 @@ static uint32_t sStackTraceDepth = 0;
 static void
 StackFrameToOStringStream(uint32_t aFrameNumber, void* aPC, void* aSP,
                           void* aClosure)
 {
   std::ostringstream* stream = static_cast<std::ostringstream*>(aClosure);
   nsCodeAddressDetails details;
   char buf[1024];
   NS_DescribeCodeAddress(aPC, &details);
-  NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
-  *stream << "--" << buf << '\n';
+  NS_FormatCodeAddressDetails(aFrameNumber, aPC, &details, buf, sizeof(buf));
+  *stream << "--" << buf;
 }
 #endif
 
 // Log to the browser console and, if DEBUG build, stderr.
 static void
 Log(const char* aMessageType,
     const char* aFunctionName,
     const char* aContext,
--- a/toolkit/xre/nsSigHandlers.cpp
+++ b/toolkit/xre/nsSigHandlers.cpp
@@ -58,18 +58,18 @@ extern "C" {
 
 static void PrintStackFrame(uint32_t aFrameNumber, void *aPC, void *aSP,
                             void *aClosure)
 {
   char buf[1024];
   nsCodeAddressDetails details;
 
   NS_DescribeCodeAddress(aPC, &details);
-  NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
-  fprintf(stdout, "%s\n", buf);
+  NS_FormatCodeAddressDetails(aFrameNumber, aPC, &details, buf, sizeof(buf));
+  fputs(buf, stdout);
 }
 
 }
 
 void
 ah_crap_handler(int signum)
 {
   printf("\nProgram %s (pid = %d) received signal %d.\n",
--- a/tools/rb/fix_linux_stack.py
+++ b/tools/rb/fix_linux_stack.py
@@ -1,17 +1,26 @@
 #!/usr/bin/python
 # vim:sw=4:ts=4:et:
 # 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/.
 
-# This script uses addr2line (part of binutils) to post-process the entries
-# produced by NS_FormatCodeAddress(), which on Linux often lack a function
-# name, a file name and a line number.
+# This script uses addr2line (part of binutils) to process the output of
+# nsTraceRefcnt's Linux stack walking code.  This is useful for two
+# things:
+#  (1) Getting line number information out of
+#      |nsTraceRefcnt::WalkTheStack|'s output in debug builds.
+#  (2) Getting function names out of |nsTraceRefcnt::WalkTheStack|'s
+#      output on optimized builds (where it mostly prints UNKNOWN
+#      because only a handful of symbols are exported from component
+#      libraries).
+#
+# Use the script by piping output containing stacks (such as raw stacks
+# or make-tree.pl balance trees) through this script.
 
 import subprocess
 import sys
 import re
 import os
 import pty
 import termios
 from StringIO import StringIO
@@ -282,30 +291,35 @@ def addressToSymbol(file, address):
     else:
         (converter, address_adjustment, cache) = addr2lines[file]
     if address in cache:
         return cache[address]
     result = converter.convert(hex(int(address, 16) + address_adjustment))
     cache[address] = result
     return result
 
-# Matches lines produced by NS_FormatCodeAddress().
-line_re = re.compile("^(.*#\d+: )(.+)\[(.+) \+(0x.+)\](.*)$")
+line_re = re.compile("^(.*) ?\[([^ ]*) \+(0x[0-9A-F]{1,8})\](.*)$")
+balance_tree_re = re.compile("^([ \|0-9-]*)(.*)$")
 
 def fixSymbols(line):
     result = line_re.match(line)
     if result is not None:
-        (before, fn, file, address, after) = result.groups()
+        # before allows preservation of balance trees
+        # after allows preservation of counts
+        (before, file, address, after) = result.groups()
 
         if os.path.exists(file) and os.path.isfile(file):
+            # throw away the bad symbol, but keep balance tree structure
+            (before, badsymbol) = balance_tree_re.match(before).groups()
+
             (name, fileline) = addressToSymbol(file, address)
 
             # If addr2line gave us something useless, keep what we had before.
             if name == "??":
-                name = fn
+                name = badsymbol
             if fileline == "??:0" or fileline == "??:?":
                 fileline = file
 
             nl = '\n' if line[-1] == '\n' else ''
             return "%s%s (%s)%s%s" % (before, name, fileline, after, nl)
         else:
             sys.stderr.write("Warning: File \"" + file + "\" does not exist.\n")
             return line
--- a/tools/rb/fix_macosx_stack.py
+++ b/tools/rb/fix_macosx_stack.py
@@ -1,17 +1,24 @@
 #!/usr/bin/python
 # vim:sw=4:ts=4:et:
 # 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/.
 
-# This script uses |atos| to post-process the entries produced by
-# NS_FormatCodeAddress(), which on Mac often lack a file name and a line
-# number.
+# This script uses atos to process the output of nsTraceRefcnt's Mac OS
+# X stack walking code.  This is useful for two things:
+#  (1) Getting line number information out of
+#      |nsTraceRefcnt::WalkTheStack|'s output in debug builds.
+#  (2) Getting function names out of |nsTraceRefcnt::WalkTheStack|'s
+#      output on all builds (where it mostly prints UNKNOWN because only
+#      a handful of symbols are exported from component libraries).
+#
+# Use the script by piping output containing stacks (such as raw stacks
+# or make-tree.pl balance trees) through this script.
 
 import subprocess
 import sys
 import re
 import os
 import pty
 import termios
 
@@ -87,24 +94,26 @@ def cxxfilt(sym):
         globals()["cxxfilt_proc"] = subprocess.Popen(['c++filt',
                                                       '--no-strip-underscores',
                                                       '--format', 'gnu-v3'],
                                                      stdin=subprocess.PIPE,
                                                      stdout=subprocess.PIPE)
     cxxfilt_proc.stdin.write(sym + "\n")
     return cxxfilt_proc.stdout.readline().rstrip("\n")
 
-# Matches lines produced by NS_FormatCodeAddress().
-line_re = re.compile("^(.*#\d+: )(.+)\[(.+) \+(0x.+)\](.*)$")
+line_re = re.compile("^(.*) ?\[([^ ]*) \+(0x[0-9a-fA-F]{1,8})\](.*)$")
+balance_tree_re = re.compile("^([ \|0-9-]*)")
 atos_name_re = re.compile("^(.+) \(in ([^)]+)\) \((.+)\)$")
 
 def fixSymbols(line):
     result = line_re.match(line)
     if result is not None:
-        (before, fn, file, address, after) = result.groups()
+        # before allows preservation of balance trees
+        # after allows preservation of counts
+        (before, file, address, after) = result.groups()
         address = int(address, 16)
 
         if os.path.exists(file) and os.path.isfile(file):
             address += address_adjustment(file)
             info = addressToSymbol(file, address)
 
             # atos output seems to have three forms:
             #   address
@@ -115,16 +124,19 @@ def fixSymbols(line):
                 # Print the first two forms as-is, and transform the third
                 (name, library, fileline) = name_result.groups()
                 # atos demangles, but occasionally it fails.  cxxfilt can mop
                 # up the remaining cases(!), which will begin with '_Z'.
                 if (name.startswith("_Z")):
                     name = cxxfilt(name)
                 info = "%s (%s, in %s)" % (name, fileline, library)
 
+            # throw away the bad symbol, but keep balance tree structure
+            before = balance_tree_re.match(before).groups()[0]
+
             nl = '\n' if line[-1] == '\n' else ''
             return before + info + after + nl
         else:
             sys.stderr.write("Warning: File \"" + file + "\" does not exist.\n")
             return line
     else:
         return line
 
--- a/tools/rb/fix_stack_using_bpsyms.py
+++ b/tools/rb/fix_stack_using_bpsyms.py
@@ -1,18 +1,14 @@
 #!/usr/bin/env python
 
 # 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/.
 
-# This script uses breakpad symbols to post-process the entries produced by
-# NS_FormatCodeAddress(), which on TBPL builds often lack a file name and a
-# line number (and on Linux even the symbol is often bad).
-
 from __future__ import with_statement
 
 import sys
 import os
 import re
 import bisect
 
 def prettyFileName(name):
@@ -111,24 +107,28 @@ def getSymbolFile(file, symbolsDir):
 
 def addressToSymbol(file, address, symbolsDir):
   p = getSymbolFile(file, symbolsDir)
   if p:
     return p.addrToSymbol(address)
   else:
     return ""
 
-# Matches lines produced by NS_FormatCodeAddress().
-line_re = re.compile("^(.*#\d+: )(.+)\[(.+) \+(0x.+)\](.*)$")
+line_re = re.compile("^(.*) ?\[([^ ]*) \+(0x[0-9A-F]{1,16})\](.*)$")
+balance_tree_re = re.compile("^([ \|0-9-]*)")
 
 def fixSymbols(line, symbolsDir):
   result = line_re.match(line)
   if result is not None:
-    (before, fn, file, address, after) = result.groups()
+    # before allows preservation of balance trees
+    # after allows preservation of counts
+    (before, file, address, after) = result.groups()
     address = int(address, 16)
+    # throw away the bad symbol, but keep balance tree structure
+    before = balance_tree_re.match(before).groups()[0]
     symbol = addressToSymbol(file, address, symbolsDir)
     if not symbol:
       symbol = "%s + 0x%x" % (os.path.basename(file), address)
     return before + symbol + after + "\n"
   else:
     return line
 
 if __name__ == "__main__":
--- a/tools/rb/make-tree.pl
+++ b/tools/rb/make-tree.pl
@@ -92,26 +92,21 @@ sub read_data($$$) {
           my $sno   = shift(@fields);
           next LINE unless ($obj eq $::opt_object);
      
           my $op  = shift(@fields);
           next LINE unless ($op eq $plus || $op eq $minus);
      
           my $cnt = shift(@fields);
      
-          # Collect the remaining lines to create a stack trace. We need to
-          # filter out the frame numbers so that frames that differ only in
-          # their frame number are considered equivalent. However, we need to
-          # keep a frame number on each line so that the fix*.py scripts can
-          # parse the output. So we set the frame number to 0 for every frame.
+          # Collect the remaining lines to create a stack trace.
           my @stack;
           CALLSITE: while (<$INFILE>) {
               chomp;
               last CALLSITE if (/^$/);
-              $_ =~ s/#\d+: /#00: /;    # replace frame number with 0
               $stack[++$#stack] = $_;
           }
      
           # Reverse the remaining fields to produce the call stack, with the
           # oldest frame at the front of the array.
           if (! $::opt_reverse) {
               @stack = reverse(@stack);
           }
--- a/xpcom/base/CodeAddressService.h
+++ b/xpcom/base/CodeAddressService.h
@@ -84,19 +84,22 @@ class CodeAddressService
     void Replace(const void* aPc, const char* aFunction,
                  const char* aLibrary, ptrdiff_t aLOffset,
                  const char* aFileName, unsigned long aLineNo)
     {
       mPc = aPc;
 
       // Convert "" to nullptr.  Otherwise, make a copy of the name.
       StringAlloc::free(mFunction);
-      mFunction = !aFunction[0] ? nullptr : StringAlloc::copy(aFunction);
+      mFunction =
+        !aFunction[0] ? nullptr : StringAlloc::copy(aFunction);
       StringAlloc::free(mFileName);
-      mFileName = !aFileName[0] ? nullptr : StringAlloc::copy(aFileName);
+      mFileName =
+        !aFileName[0] ? nullptr : StringAlloc::copy(aFileName);
+
 
       mLibrary = aLibrary;
       mLOffset = aLOffset;
       mLineNo = aLineNo;
 
       mInUse = 1;
     }
 
@@ -158,19 +161,36 @@ public:
                     details.filename, details.lineno);
 
     } else {
       mNumCacheHits++;
     }
 
     MOZ_ASSERT(entry.mPc == aPc);
 
-    NS_FormatCodeAddress(aBuf, aBufLen, aFrameNumber, entry.mPc,
-                         entry.mFunction, entry.mLibrary, entry.mLOffset,
-                         entry.mFileName, entry.mLineNo);
+    uintptr_t entryPc = (uintptr_t)(entry.mPc);
+    // Sometimes we get nothing useful.  Just print "???" for the entire entry
+    // so that fix_linux_stack.py doesn't complain about an empty filename.
+    if (!entry.mFunction && !entry.mLibrary[0] && entry.mLOffset == 0) {
+      snprintf(aBuf, aBufLen, "??? 0x%" PRIxPTR, entryPc);
+    } else {
+      // Use "???" for unknown functions.
+      const char* entryFunction = entry.mFunction ? entry.mFunction : "???";
+      if (entry.mFileName) {
+        // On Windows we can get the filename and line number at runtime.
+        snprintf(aBuf, aBufLen, "%s (%s:%u) 0x%" PRIxPTR,
+                 entryFunction, entry.mFileName, entry.mLineNo, entryPc);
+      } else {
+        // On Linux and Mac we cannot get the filename and line number at
+        // runtime, so we print the offset in a form that fix_linux_stack.py and
+        // fix_macosx_stack.py can post-process.
+        snprintf(aBuf, aBufLen, "%s[%s +0x%" PRIXPTR "] 0x%" PRIxPTR,
+                 entryFunction, entry.mLibrary, entry.mLOffset, entryPc);
+      }
+    }
   }
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
   {
     size_t n = aMallocSizeOf(this);
     for (uint32_t i = 0; i < kNumEntries; i++) {
       n += mEntries[i].SizeOfExcludingThis(aMallocSizeOf);
     }
--- a/xpcom/base/nsStackWalk.cpp
+++ b/xpcom/base/nsStackWalk.cpp
@@ -8,20 +8,16 @@
 
 #include "mozilla/Assertions.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/StackWalk.h"
 #include "nsStackWalkPrivate.h"
 
 #include "nsStackWalk.h"
 
-#ifdef XP_WIN
-#define snprintf _snprintf
-#endif
-
 using namespace mozilla;
 
 // The presence of this address is the stack must stop the stack walk. If
 // there is no such address, the structure will be {nullptr, true}.
 struct CriticalAddress
 {
   void* mAddr;
   bool mInit;
@@ -826,16 +822,49 @@ NS_DescribeCodeAddress(void* aPC, nsCode
                 sizeof(aDetails->function));
     aDetails->foffset = static_cast<ptrdiff_t>(displacement);
   }
 
   LeaveCriticalSection(&gDbgHelpCS); // release our lock
   return NS_OK;
 }
 
+EXPORT_XPCOM_API(nsresult)
+NS_FormatCodeAddressDetails(uint32_t aFrameNumber, void* aPC,
+                            const nsCodeAddressDetails* aDetails,
+                            char* aBuffer, uint32_t aBufferSize)
+{
+  if (aDetails->function[0]) {
+    _snprintf(aBuffer, aBufferSize, "%s+0x%08lX [%s +0x%016lX]",
+              aDetails->function, aDetails->foffset,
+              aDetails->library, aDetails->loffset);
+  } else if (aDetails->library[0]) {
+    _snprintf(aBuffer, aBufferSize, "UNKNOWN [%s +0x%016lX]",
+              aDetails->library, aDetails->loffset);
+  } else {
+    _snprintf(aBuffer, aBufferSize, "UNKNOWN 0x%016lX", aPC);
+  }
+
+  aBuffer[aBufferSize - 1] = '\0';
+
+  uint32_t len = strlen(aBuffer);
+  if (aDetails->filename[0]) {
+    _snprintf(aBuffer + len, aBufferSize - len, " (%s, line %d)\n",
+              aDetails->filename, aDetails->lineno);
+  } else {
+    aBuffer[len] = '\n';
+    if (++len != aBufferSize) {
+      aBuffer[len] = '\0';
+    }
+  }
+  aBuffer[aBufferSize - 2] = '\n';
+  aBuffer[aBufferSize - 1] = '\0';
+  return NS_OK;
+}
+
 // i386 or PPC Linux stackwalking code
 #elif HAVE_DLADDR && (HAVE__UNWIND_BACKTRACE || NSSTACKWALK_SUPPORTS_LINUX || NSSTACKWALK_SUPPORTS_MACOSX)
 
 #include <stdlib.h>
 #include <string.h>
 #include "nscore.h"
 #include <stdio.h>
 #include "plstr.h"
@@ -1068,16 +1097,35 @@ NS_DescribeCodeAddress(void* aPC, nsCode
     // Just use the mangled symbol if demangling failed.
     PL_strncpyz(aDetails->function, symbol, sizeof(aDetails->function));
   }
 
   aDetails->foffset = (char*)aPC - (char*)info.dli_saddr;
   return NS_OK;
 }
 
+EXPORT_XPCOM_API(nsresult)
+NS_FormatCodeAddressDetails(uint32_t aFrameNumber, void* aPC,
+                            const nsCodeAddressDetails* aDetails,
+                            char* aBuffer, uint32_t aBufferSize)
+{
+  if (!aDetails->library[0]) {
+    snprintf(aBuffer, aBufferSize, "UNKNOWN %p\n", aPC);
+  } else if (!aDetails->function[0]) {
+    snprintf(aBuffer, aBufferSize, "UNKNOWN [%s +0x%08" PRIXPTR "]\n",
+             aDetails->library, aDetails->loffset);
+  } else {
+    snprintf(aBuffer, aBufferSize, "%s+0x%08" PRIXPTR
+             " [%s +0x%08" PRIXPTR "]\n",
+             aDetails->function, aDetails->foffset,
+             aDetails->library, aDetails->loffset);
+  }
+  return NS_OK;
+}
+
 #else // unsupported platform.
 
 EXPORT_XPCOM_API(nsresult)
 NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
              uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
              void* aPlatformData)
 {
   MOZ_ASSERT(!aThread);
@@ -1101,49 +1149,18 @@ NS_DescribeCodeAddress(void* aPC, nsCode
   aDetails->loffset = 0;
   aDetails->filename[0] = '\0';
   aDetails->lineno = 0;
   aDetails->function[0] = '\0';
   aDetails->foffset = 0;
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-#endif
-
-EXPORT_XPCOM_API(void)
-NS_FormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
-                            uint32_t aFrameNumber, void* aPC,
-                            const nsCodeAddressDetails* aDetails)
+EXPORT_XPCOM_API(nsresult)
+NS_FormatCodeAddressDetails(uint32_t aFrameNumber, void* aPC,
+                            const nsCodeAddressDetails* aDetails,
+                            char* aBuffer, uint32_t aBufferSize)
 {
-  NS_FormatCodeAddress(aBuffer, aBufferSize,
-                       aFrameNumber, aPC, aDetails->function,
-                       aDetails->library, aDetails->loffset,
-                       aDetails->filename, aDetails->lineno);
+  aBuffer[0] = '\0';
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-EXPORT_XPCOM_API(void)
-NS_FormatCodeAddress(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,
-             "#%02u: %s (%s:%u)",
-             aFrameNumber, function, aFileName, aLineNo);
-  } else if (aLibrary && aLibrary[0]) {
-    // We have no filename, but we do have a library name. Use it and the
-    // library offset, and print them in a way that scripts like
-    // fix_{linux,macosx}_stacks.py can easily post-process.
-    snprintf(aBuffer, aBufferSize,
-             "#%02u: %s[%s +0x%" PRIxPTR "]",
-             aFrameNumber, function, aLibrary, aLOffset);
-  } else {
-    // We have nothing useful to go on. (The format string is split because
-    // '??)' is a trigraph and causes a warning, sigh.)
-    snprintf(aBuffer, aBufferSize,
-             "#%02u: ??? (???:???" ")",
-             aFrameNumber);
-  }
-}
-
+#endif
--- a/xpcom/base/nsStackWalk.h
+++ b/xpcom/base/nsStackWalk.h
@@ -113,58 +113,29 @@ NS_DescribeCodeAddress(void* aPC, nsCode
 
 /**
  * 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.
  *
- * Note that this output is parsed by several scripts including the fix*.py and
- * make-tree.pl scripts in tools/rb/. It should only be change with care, and
- * in conjunction with those scripts.
- *
+ * @param aFrameNumber The frame number (starts at 1, not 0).
+ * @param aPC          The code address.
+ * @param aDetails     The value filled in by NS_DescribeCodeAddress(aPC).
  * @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 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,
-                     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.
- *
- * @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).
- */
-XPCOM_API(void)
-NS_FormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
-                            uint32_t aFrameNumber, void* aPC,
-                            const nsCodeAddressDetails* aDetails);
+XPCOM_API(nsresult)
+NS_FormatCodeAddressDetails(uint32_t aFrameNumber, void* aPC,
+                            const nsCodeAddressDetails* aDetails,
+                            char* aBuffer, uint32_t aBufferSize);
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* !defined(nsStackWalk_h_) */
--- a/xpcom/base/nsTraceRefcnt.cpp
+++ b/xpcom/base/nsTraceRefcnt.cpp
@@ -931,18 +931,18 @@ extern "C" {
 static void
 PrintStackFrame(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
 {
   FILE* stream = (FILE*)aClosure;
   nsCodeAddressDetails details;
   char buf[1024];
 
   NS_DescribeCodeAddress(aPC, &details);
-  NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
-  fprintf(stream, "%s\n", buf);
+  NS_FormatCodeAddressDetails(aFrameNumber, aPC, &details, buf, sizeof(buf));
+  fputs(buf, stream);
 }
 
 static void
 PrintStackFrameCached(uint32_t aFrameNumber, void* aPC, void* aSP,
                       void* aClosure)
 {
   auto stream = static_cast<FILE*>(aClosure);
   static const size_t buflen = 1024;
--- a/xpcom/glue/BlockingResourceBase.cpp
+++ b/xpcom/glue/BlockingResourceBase.cpp
@@ -180,17 +180,17 @@ BlockingResourceBase::Print(nsACString& 
 #ifdef MOZ_CALLSTACK_DISABLED
   fputs("  [stack trace unavailable]\n", stderr);
 #else
   const AcquisitionState& state = acquired ? mAcquired : mFirstSeen;
 
   WalkTheStackCodeAddressService addressService;
 
   for (uint32_t i = 0; i < state.Length(); i++) {
-    const size_t kMaxLength = 1024;
+    const size_t kMaxLength = 4096;
     char buffer[kMaxLength];
     addressService.GetLocation(state[i], buffer, kMaxLength);
     const char* fmt = "    %s\n";
     aOut += nsPrintfCString(fmt, buffer);
     fprintf(stderr, fmt, buffer);
   }
 
 #endif