src: print backtrace on fatal error
Print a C backtrace on fatal errors to make it easier to debug issues like https://github.com/nodejs/node/issues/6727. PR-URL: https://github.com/nodejs/node/pull/6734 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
3c85f4e237
commit
787eddf794
2
node.gyp
2
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
|
||||
|
50
src/backtrace_posix.cc
Normal file
50
src/backtrace_posix.cc
Normal file
@ -0,0 +1,50 @@
|
||||
#include "node.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <features.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(__GLIBC__)
|
||||
#define HAVE_EXECINFO_H 0
|
||||
#else
|
||||
#define HAVE_EXECINFO_H 1
|
||||
#endif
|
||||
|
||||
#if HAVE_EXECINFO_H
|
||||
#include <cxxabi.h>
|
||||
#include <dlfcn.h>
|
||||
#include <execinfo.h>
|
||||
#include <stdio.h>
|
||||
#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
|
8
src/backtrace_win32.cc
Normal file
8
src/backtrace_win32.cc
Normal file
@ -0,0 +1,8 @@
|
||||
#include "node.h"
|
||||
|
||||
namespace node {
|
||||
|
||||
void DumpBacktrace(FILE* fp) {
|
||||
}
|
||||
|
||||
} // namespace node
|
@ -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();
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -18,6 +19,8 @@
|
||||
|
||||
namespace node {
|
||||
|
||||
void DumpBacktrace(FILE* fp);
|
||||
|
||||
#ifdef __APPLE__
|
||||
template <typename T> using remove_reference = std::tr1::remove_reference<T>;
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user