V8_Fatal now prints C++ stack trace in debug mode.
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 14 Dec 2012 14:27:06 +0000 (14:27 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 14 Dec 2012 14:27:06 +0000 (14:27 +0000)
Currently only supported on Linux. When compiled with GCC, also demangles C++ identifier names.

Should make debugging those flaky crashes on buildbots easier... :)

R=mstarzinger@chromium.org,ulan@chromium.org
BUG=

Review URL: https://codereview.chromium.org/11577019

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13222 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

12 files changed:
Makefile
build/common.gypi
build/standalone.gypi
src/checks.cc
src/isolate.cc
src/platform-linux.cc
src/platform-macos.cc
src/platform-nullos.cc
src/platform-openbsd.cc
src/platform-solaris.cc
src/platform-win32.cc
src/platform.h

index b65ea4c..4502088 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -62,6 +62,12 @@ endif
 ifeq ($(verifyheap), on)
   GYPFLAGS += -Dv8_enable_verify_heap=1
 endif
+# backtrace=off
+ifeq ($(backtrace), off)
+  GYPFLAGS += -Dv8_enable_backtrace=0
+else
+  GYPFLAGS += -Dv8_enable_backtrace=1
+endif
 # snapshot=off
 ifeq ($(snapshot), off)
   GYPFLAGS += -Dv8_use_snapshot='false'
index e68ee15..7e7b1b4 100644 (file)
@@ -68,6 +68,8 @@
 
     'v8_enable_debugger_support%': 1,
 
+    'v8_enable_backtrace%': 0,
+
     'v8_enable_disassembler%': 0,
 
     'v8_enable_gdbjit%': 0,
             'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
                         '-Wnon-virtual-dtor', '-Woverloaded-virtual' ],
           }],
+          ['OS=="linux" and v8_enable_backtrace==1', {
+            # Support for backtrace_symbols.
+            'ldflags': [ '-rdynamic' ],
+          }],
           ['OS=="android"', {
             'variables': {
               'android_full_debug%': 1,
index 7145a16..84bdc97 100644 (file)
           [ 'OS=="linux"', {
             'cflags': [ '-ansi' ],
           }],
-          [ 'visibility=="hidden"', {
+          [ 'visibility=="hidden" and v8_enable_backtrace==0', {
             'cflags': [ '-fvisibility=hidden' ],
           }],
           [ 'component=="shared_library"', {
index 320fd6b..a6405ec 100644 (file)
@@ -46,7 +46,8 @@ extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) {
     va_start(arguments, format);
     i::OS::VPrintError(format, arguments);
     va_end(arguments);
-    i::OS::PrintError("\n#\n\n");
+    i::OS::PrintError("\n#\n");
+    i::OS::DumpBacktrace();
   }
   // First two times we may try to print a stack dump.
   if (fatal_error_handler_nesting_depth < 3) {
index b760aeb..7c06903 100644 (file)
@@ -812,7 +812,7 @@ static void PrintFrames(StringStream* accumulator,
 void Isolate::PrintStack(StringStream* accumulator) {
   if (!IsInitialized()) {
     accumulator->Add(
-        "\n==== Stack trace is not available ==========================\n\n");
+        "\n==== JS stack trace is not available =======================\n\n");
     accumulator->Add(
         "\n==== Isolate for the thread is not initialized =============\n\n");
     return;
@@ -825,7 +825,7 @@ void Isolate::PrintStack(StringStream* accumulator) {
   if (c_entry_fp(thread_local_top()) == 0) return;
 
   accumulator->Add(
-      "\n==== Stack trace ============================================\n\n");
+      "\n==== JS stack trace =========================================\n\n");
   PrintFrames(accumulator, StackFrame::OVERVIEW);
 
   accumulator->Add(
index 8022ba2..ce45bab 100644 (file)
 #include <sys/types.h>
 #include <stdlib.h>
 
+#if defined(__GLIBC__)
+#include <execinfo.h>
+#include <cxxabi.h>
+#endif
+
 // Ubuntu Dapper requires memory pages to be marked as
 // executable. Otherwise, OS raises an exception when executing code
 // in that page.
@@ -415,6 +420,37 @@ void OS::DebugBreak() {
 }
 
 
+void OS::DumpBacktrace() {
+#if defined(__GLIBC__)
+  void* trace[100];
+  int size = backtrace(trace, ARRAY_SIZE(trace));
+  char** symbols = backtrace_symbols(trace, size);
+  fprintf(stderr, "\n==== C stack trace ===============================\n\n");
+  if (size == 0) {
+    fprintf(stderr, "(empty)\n");
+  } else if (symbols == NULL) {
+    fprintf(stderr, "(no symbols)\n");
+  } else {
+    for (int i = 1; i < size; ++i) {
+      fprintf(stderr, "%2d: ", i);
+      char mangled[201];
+      if (sscanf(symbols[i], "%*[^(]%*[(]%200[^)+]", mangled) == 1) {  // NOLINT
+        int status;
+        size_t length;
+        char* demangled = abi::__cxa_demangle(mangled, NULL, &length, &status);
+        fprintf(stderr, "%s\n", demangled ? demangled : mangled);
+        free(demangled);
+      } else {
+        fprintf(stderr, "??\n");
+      }
+    }
+  }
+  fflush(stderr);
+  free(symbols);
+#endif
+}
+
+
 class PosixMemoryMappedFile : public OS::MemoryMappedFile {
  public:
   PosixMemoryMappedFile(FILE* file, void* memory, int size)
index 20db4e4..899405e 100644 (file)
@@ -182,6 +182,11 @@ void OS::DebugBreak() {
 }
 
 
+void OS::DumpBacktrace() {
+  // Currently unsupported.
+}
+
+
 class PosixMemoryMappedFile : public OS::MemoryMappedFile {
  public:
   PosixMemoryMappedFile(FILE* file, void* memory, int size)
index ccd2123..f5ae5ec 100644 (file)
@@ -277,6 +277,11 @@ void OS::DebugBreak() {
 }
 
 
+void OS::DumpBacktrace() {
+  // Currently unsupported.
+}
+
+
 OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
   UNIMPLEMENTED();
   return NULL;
index 48ca2e8..7fdd5b2 100644 (file)
@@ -215,6 +215,11 @@ void OS::DebugBreak() {
 }
 
 
+void OS::DumpBacktrace() {
+  // Currently unsupported.
+}
+
+
 class PosixMemoryMappedFile : public OS::MemoryMappedFile {
  public:
   PosixMemoryMappedFile(FILE* file, void* memory, int size)
index 85a08d2..9724cd1 100644 (file)
@@ -202,6 +202,11 @@ void OS::DebugBreak() {
 }
 
 
+void OS::DumpBacktrace() {
+  // Currently unsupported.
+}
+
+
 class PosixMemoryMappedFile : public OS::MemoryMappedFile {
  public:
   PosixMemoryMappedFile(FILE* file, void* memory, int size)
index be0e31d..0f0143a 100644 (file)
@@ -987,6 +987,11 @@ void OS::DebugBreak() {
 }
 
 
+void OS::DumpBacktrace() {
+  // Currently unsupported.
+}
+
+
 class Win32MemoryMappedFile : public OS::MemoryMappedFile {
  public:
   Win32MemoryMappedFile(HANDLE file,
index 6f75ca8..a1036c4 100644 (file)
@@ -245,6 +245,9 @@ class OS {
   // Debug break.
   static void DebugBreak();
 
+  // Dump C++ current stack trace (only functional on Linux).
+  static void DumpBacktrace();
+
   // Walk the stack.
   static const int kStackWalkError = -1;
   static const int kStackWalkMaxNameLen = 256;