From: rossberg@chromium.org Date: Fri, 14 Dec 2012 14:27:06 +0000 (+0000) Subject: V8_Fatal now prints C++ stack trace in debug mode. X-Git-Tag: upstream/4.7.83~15430 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9fc844b760f04de48a050be68c2890d5fe02ef55;p=platform%2Fupstream%2Fv8.git V8_Fatal now prints C++ stack trace in debug mode. 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 --- diff --git a/Makefile b/Makefile index b65ea4c..4502088 100644 --- 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' diff --git a/build/common.gypi b/build/common.gypi index e68ee15..7e7b1b4 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -68,6 +68,8 @@ 'v8_enable_debugger_support%': 1, + 'v8_enable_backtrace%': 0, + 'v8_enable_disassembler%': 0, 'v8_enable_gdbjit%': 0, @@ -368,6 +370,10 @@ '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, diff --git a/build/standalone.gypi b/build/standalone.gypi index 7145a16..84bdc97 100644 --- a/build/standalone.gypi +++ b/build/standalone.gypi @@ -100,7 +100,7 @@ [ 'OS=="linux"', { 'cflags': [ '-ansi' ], }], - [ 'visibility=="hidden"', { + [ 'visibility=="hidden" and v8_enable_backtrace==0', { 'cflags': [ '-fvisibility=hidden' ], }], [ 'component=="shared_library"', { diff --git a/src/checks.cc b/src/checks.cc index 320fd6b..a6405ec 100644 --- a/src/checks.cc +++ b/src/checks.cc @@ -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) { diff --git a/src/isolate.cc b/src/isolate.cc index b760aeb..7c06903 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -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( diff --git a/src/platform-linux.cc b/src/platform-linux.cc index 8022ba2..ce45bab 100644 --- a/src/platform-linux.cc +++ b/src/platform-linux.cc @@ -38,6 +38,11 @@ #include #include +#if defined(__GLIBC__) +#include +#include +#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) diff --git a/src/platform-macos.cc b/src/platform-macos.cc index 20db4e4..899405e 100644 --- a/src/platform-macos.cc +++ b/src/platform-macos.cc @@ -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) diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc index ccd2123..f5ae5ec 100644 --- a/src/platform-nullos.cc +++ b/src/platform-nullos.cc @@ -277,6 +277,11 @@ void OS::DebugBreak() { } +void OS::DumpBacktrace() { + // Currently unsupported. +} + + OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { UNIMPLEMENTED(); return NULL; diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc index 48ca2e8..7fdd5b2 100644 --- a/src/platform-openbsd.cc +++ b/src/platform-openbsd.cc @@ -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) diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc index 85a08d2..9724cd1 100644 --- a/src/platform-solaris.cc +++ b/src/platform-solaris.cc @@ -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) diff --git a/src/platform-win32.cc b/src/platform-win32.cc index be0e31d..0f0143a 100644 --- a/src/platform-win32.cc +++ b/src/platform-win32.cc @@ -987,6 +987,11 @@ void OS::DebugBreak() { } +void OS::DumpBacktrace() { + // Currently unsupported. +} + + class Win32MemoryMappedFile : public OS::MemoryMappedFile { public: Win32MemoryMappedFile(HANDLE file, diff --git a/src/platform.h b/src/platform.h index 6f75ca8..a1036c4 100644 --- a/src/platform.h +++ b/src/platform.h @@ -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;