diff --git a/node.gyp b/node.gyp index 43c0de6f8504a8..51fe580af7d33c 100644 --- a/node.gyp +++ b/node.gyp @@ -466,6 +466,7 @@ [ 'OS=="win"', { 'sources': [ + 'src/backtrace_win32.cc', 'src/res/node.rc', ], 'defines!': [ @@ -480,6 +481,7 @@ 'libraries': [ '-lpsapi.lib' ] }, { # POSIX 'defines': [ '__POSIX__' ], + 'sources': [ 'src/backtrace_posix.cc' ], }], [ 'OS=="mac"', { # linking Corefoundation is needed since certain OSX debugging tools diff --git a/src/backtrace_posix.cc b/src/backtrace_posix.cc new file mode 100644 index 00000000000000..468d9784528b0f --- /dev/null +++ b/src/backtrace_posix.cc @@ -0,0 +1,50 @@ +#include "node.h" + +#if defined(__linux__) +#include +#endif + +#if defined(__linux__) && !defined(__GLIBC__) +#define HAVE_EXECINFO_H 0 +#else +#define HAVE_EXECINFO_H 1 +#endif + +#if HAVE_EXECINFO_H +#include +#include +#include +#include +#endif + +namespace node { + +void DumpBacktrace(FILE* fp) { +#if HAVE_EXECINFO_H + void* frames[256]; + const int size = backtrace(frames, arraysize(frames)); + if (size <= 0) { + return; + } + for (int i = 1; i < size; i += 1) { + void* frame = frames[i]; + fprintf(fp, "%2d: ", i); + Dl_info info; + const bool have_info = dladdr(frame, &info); + if (!have_info || info.dli_sname == nullptr) { + fprintf(fp, "%p", frame); + } else if (char* demangled = abi::__cxa_demangle(info.dli_sname, 0, 0, 0)) { + fprintf(fp, "%s", demangled); + free(demangled); + } else { + fprintf(fp, "%s", info.dli_sname); + } + if (have_info && info.dli_fname != nullptr) { + fprintf(fp, " [%s]", info.dli_fname); + } + fprintf(fp, "\n"); + } +#endif // HAVE_EXECINFO_H +} + +} // namespace node diff --git a/src/backtrace_win32.cc b/src/backtrace_win32.cc new file mode 100644 index 00000000000000..71610fd663bb3c --- /dev/null +++ b/src/backtrace_win32.cc @@ -0,0 +1,8 @@ +#include "node.h" + +namespace node { + +void DumpBacktrace(FILE* fp) { +} + +} // namespace node diff --git a/src/node.cc b/src/node.cc index eaf642b76a9975..6d4c9fa1600f70 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2398,6 +2398,7 @@ static void OnFatalError(const char* location, const char* message) { } else { PrintErrorString("FATAL ERROR: %s\n", message); } + DumpBacktrace(stderr); fflush(stderr); ABORT(); } diff --git a/src/util.h b/src/util.h index 1570c57f195c66..94278e2b9fc5e5 100644 --- a/src/util.h +++ b/src/util.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #ifdef __APPLE__ @@ -18,6 +19,8 @@ namespace node { +void DumpBacktrace(FILE* fp); + #ifdef __APPLE__ template using remove_reference = std::tr1::remove_reference; #else