Skip to content

Commit 6cec90a

Browse files
bnoordhuisFishrock123
authored andcommitted
src: print backtrace on fatal error
Print a C backtrace on fatal errors to make it easier to debug issues like #6727. PR-URL: #6734 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 6de80fc commit 6cec90a

File tree

5 files changed

+64
-0
lines changed

5 files changed

+64
-0
lines changed

node.gyp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@
470470

471471
[ 'OS=="win"', {
472472
'sources': [
473+
'src/backtrace_win32.cc',
473474
'src/res/node.rc',
474475
],
475476
'defines!': [
@@ -484,6 +485,7 @@
484485
'libraries': [ '-lpsapi.lib' ]
485486
}, { # POSIX
486487
'defines': [ '__POSIX__' ],
488+
'sources': [ 'src/backtrace_posix.cc' ],
487489
}],
488490
[ 'OS=="mac"', {
489491
# linking Corefoundation is needed since certain OSX debugging tools

src/backtrace_posix.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "node.h"
2+
3+
#if defined(__linux__)
4+
#include <features.h>
5+
#endif
6+
7+
#if defined(__linux__) && !defined(__GLIBC__)
8+
#define HAVE_EXECINFO_H 0
9+
#else
10+
#define HAVE_EXECINFO_H 1
11+
#endif
12+
13+
#if HAVE_EXECINFO_H
14+
#include <cxxabi.h>
15+
#include <dlfcn.h>
16+
#include <execinfo.h>
17+
#include <stdio.h>
18+
#endif
19+
20+
namespace node {
21+
22+
void DumpBacktrace(FILE* fp) {
23+
#if HAVE_EXECINFO_H
24+
void* frames[256];
25+
const int size = backtrace(frames, arraysize(frames));
26+
if (size <= 0) {
27+
return;
28+
}
29+
for (int i = 1; i < size; i += 1) {
30+
void* frame = frames[i];
31+
fprintf(fp, "%2d: ", i);
32+
Dl_info info;
33+
const bool have_info = dladdr(frame, &info);
34+
if (!have_info || info.dli_sname == nullptr) {
35+
fprintf(fp, "%p", frame);
36+
} else if (char* demangled = abi::__cxa_demangle(info.dli_sname, 0, 0, 0)) {
37+
fprintf(fp, "%s", demangled);
38+
free(demangled);
39+
} else {
40+
fprintf(fp, "%s", info.dli_sname);
41+
}
42+
if (have_info && info.dli_fname != nullptr) {
43+
fprintf(fp, " [%s]", info.dli_fname);
44+
}
45+
fprintf(fp, "\n");
46+
}
47+
#endif // HAVE_EXECINFO_H
48+
}
49+
50+
} // namespace node

src/backtrace_win32.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "node.h"
2+
3+
namespace node {
4+
5+
void DumpBacktrace(FILE* fp) {
6+
}
7+
8+
} // namespace node

src/node.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,6 +2452,7 @@ static void OnFatalError(const char* location, const char* message) {
24522452
} else {
24532453
PrintErrorString("FATAL ERROR: %s\n", message);
24542454
}
2455+
DumpBacktrace(stderr);
24552456
fflush(stderr);
24562457
ABORT();
24572458
}

src/util.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <assert.h>
99
#include <signal.h>
1010
#include <stddef.h>
11+
#include <stdio.h>
1112
#include <stdlib.h>
1213

1314
#ifdef __APPLE__
@@ -18,6 +19,8 @@
1819

1920
namespace node {
2021

22+
void DumpBacktrace(FILE* fp);
23+
2124
#ifdef __APPLE__
2225
template <typename T> using remove_reference = std::tr1::remove_reference<T>;
2326
#else

0 commit comments

Comments
 (0)