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'
'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,
[ 'OS=="linux"', {
'cflags': [ '-ansi' ],
}],
- [ 'visibility=="hidden"', {
+ [ 'visibility=="hidden" and v8_enable_backtrace==0', {
'cflags': [ '-fvisibility=hidden' ],
}],
[ 'component=="shared_library"', {
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) {
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;
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(
#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.
}
+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)
}
+void OS::DumpBacktrace() {
+ // Currently unsupported.
+}
+
+
class PosixMemoryMappedFile : public OS::MemoryMappedFile {
public:
PosixMemoryMappedFile(FILE* file, void* memory, int size)
}
+void OS::DumpBacktrace() {
+ // Currently unsupported.
+}
+
+
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
UNIMPLEMENTED();
return NULL;
}
+void OS::DumpBacktrace() {
+ // Currently unsupported.
+}
+
+
class PosixMemoryMappedFile : public OS::MemoryMappedFile {
public:
PosixMemoryMappedFile(FILE* file, void* memory, int size)
}
+void OS::DumpBacktrace() {
+ // Currently unsupported.
+}
+
+
class PosixMemoryMappedFile : public OS::MemoryMappedFile {
public:
PosixMemoryMappedFile(FILE* file, void* memory, int size)
}
+void OS::DumpBacktrace() {
+ // Currently unsupported.
+}
+
+
class Win32MemoryMappedFile : public OS::MemoryMappedFile {
public:
Win32MemoryMappedFile(HANDLE file,
// 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;