Bug 644707 - Avoid calling system abort(), generate useful stack traces through a manual segfault instead. r=ted
authorAlon Zakai <azakai@mozilla.com>
Thu, 07 Jul 2011 14:09:52 -0700
changeset 72502 f986c9b02c1dc5d5200e7c691c2f7746de2a58fb
parent 72501 8edd1224feed1dc91376aea2dd3fe55a2bc7c39b
child 72503 5179f07def0c4b328d51e12c2d0b410eae5ea811
push id20728
push usermak77@bonardo.net
push dateFri, 08 Jul 2011 09:54:33 +0000
treeherdermozilla-central@5479a346b95b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs644707
milestone8.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 644707 - Avoid calling system abort(), generate useful stack traces through a manual segfault instead. r=ted
memory/mozalloc/mozalloc_abort.cpp
--- a/memory/mozalloc/mozalloc_abort.cpp
+++ b/memory/mozalloc/mozalloc_abort.cpp
@@ -42,16 +42,17 @@
 #include <stdlib.h>             // for abort()
 
 #if defined(_MSC_VER)           // MSVC
 #  include <intrin.h>           // for __debugbreak()
 #elif defined(XP_WIN)           // mingw
 #  include <windows.h>          // for DebugBreak
 #elif defined(XP_UNIX)
 #  include <unistd.h>           // for _exit
+#  include <signal.h>
 #endif
 
 #if defined(XP_WIN) || defined(XP_OS2)
 #  define MOZALLOC_EXPORT __declspec(dllexport)
 #endif
 
 #include "mozilla/mozalloc_abort.h"
 
@@ -67,24 +68,44 @@ TouchBadMemory()
 }
 
 void
 mozalloc_abort(const char* const msg)
 {
     fputs(msg, stderr);
     fputs("\n", stderr);
 
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-    abort();
-#elif defined(_MSC_VER)
+#if defined(_MSC_VER)
     __debugbreak();
 #elif defined(XP_WIN)
     DebugBreak();
 #endif
-    // abort() doesn't trigger breakpad on Mac, "fall through" to the
-    // fail-safe code
+
+    // On *NIX platforms the prefered way to abort is by touching bad memory,
+    // since this generates a stack trace inside our own code (avoiding
+    // problems with starting the trace inside libc, where we might not have
+    // symbols and can get lost).
+
+    TouchBadMemory();
 
-    // Still haven't aborted?  Try dereferencing null.
-    TouchBadMemory();
+    // If we haven't aborted yet, we can try to raise SIGABRT which might work
+    // on some *NIXs, but not OS X (it doesn't trigger breakpad there).
+    // Note that we don't call abort(), since raise is likelier to give us
+    // useful stack data, and also since abort() is redirected to call this
+    // function (see below).
+#if defined(XP_UNIX) && !defined(XP_MACOSX)
+    raise(SIGABRT);
+#endif
 
     // Still haven't aborted?  Try _exit().
     _exit(127);
 }
+
+#if defined(XP_UNIX)
+// Define abort() here, so that it is used instead of the system abort(). This
+// lets us control the behavior when aborting, in order to get better results
+// on *NIX platfrorms. See mozalloc_abort for details.
+void abort(void)
+{
+  mozalloc_abort("Redirecting call to abort() to mozalloc_abort\n");
+}
+#endif
+