Bug 1066760 - Use more detailed abort message on Android; r=snorp
authorJim Chen <nchen@mozilla.com>
Wed, 24 Sep 2014 14:12:54 -0400
changeset 207080 4cf6c10a0ab9cc18f46f876a86fbe84ec82a5eee
parent 207079 421c30629ac5bca71a03dead2a7d8889609e188d
child 207081 0dc44f76d6e16900e05b33649d576f32ee42fefc
push id27544
push userryanvm@gmail.com
push dateWed, 24 Sep 2014 21:10:36 +0000
treeherdermozilla-central@1735ff2bb23e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1066760
milestone35.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 1066760 - Use more detailed abort message on Android; r=snorp
memory/mozalloc/mozalloc_abort.cpp
--- a/memory/mozalloc/mozalloc_abort.cpp
+++ b/memory/mozalloc/mozalloc_abort.cpp
@@ -11,16 +11,17 @@
 
 #include "mozilla/mozalloc_abort.h"
 
 #ifdef ANDROID
 # include <android/log.h>
 #endif
 #ifdef MOZ_WIDGET_ANDROID
 # include "APKOpen.h"
+# include "dlfcn.h"
 #endif
 #include <stdio.h>
 
 #include "mozilla/Assertions.h"
 
 void
 mozalloc_abort(const char* const msg)
 {
@@ -31,18 +32,47 @@ mozalloc_abort(const char* const msg)
     __android_log_print(ANDROID_LOG_ERROR, "Gecko", "mozalloc_abort: %s", msg);
 #endif
 #ifdef MOZ_WIDGET_ANDROID
     abortThroughJava(msg);
 #endif
     MOZ_CRASH();
 }
 
+#ifdef MOZ_WIDGET_ANDROID
+template <size_t N>
+void fillAbortMessage(char (&msg)[N], uintptr_t retAddress) {
+    /*
+     * On Android, we often don't have reliable backtrace when crashing inside
+     * abort(). Therefore, we try to find out who is calling abort() and add
+     * that to the message.
+     */
+    Dl_info info = {};
+    dladdr(reinterpret_cast<void*>(retAddress), &info);
+
+    const char* const module = info.dli_fname ? info.dli_fname : "";
+    const char* const base_module = strrchr(module, '/');
+    const void* const module_offset =
+        reinterpret_cast<void*>(retAddress - uintptr_t(info.dli_fbase));
+    const char* const sym = info.dli_sname ? info.dli_sname : "";
+
+    snprintf(msg, sizeof(msg), "abort() called from %s:%p (%s)",
+             base_module ? base_module + 1 : module, module_offset, sym);
+}
+#endif
+
 #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 platforms. See mozalloc_abort for details.
 void abort(void)
 {
-    mozalloc_abort("Redirecting call to abort() to mozalloc_abort\n");
+#ifdef MOZ_WIDGET_ANDROID
+    char msg[64] = {};
+    fillAbortMessage(msg, uintptr_t(__builtin_return_address(0)));
+#else
+    const char* const msg = "Redirecting call to abort() to mozalloc_abort\n";
+#endif
+
+    mozalloc_abort(msg);
 }
 #endif