Skip to content

Commit 6f805c6

Browse files
addaleaxMylesBorins
authored andcommitted
src: implement backtrace-on-abort for windows
PR-URL: #16951 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent a6b6acb commit 6f805c6

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

src/backtrace_win32.cc

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,40 @@
1-
#include "node.h"
1+
#include "node_internals.h"
2+
#include <windows.h>
3+
#include <dbghelp.h>
24

35
namespace node {
46

57
void DumpBacktrace(FILE* fp) {
8+
void* frames[256];
9+
int size = CaptureStackBackTrace(0, arraysize(frames), frames, nullptr);
10+
HANDLE process = GetCurrentProcess();
11+
(void)SymInitialize(process, nullptr, true);
12+
13+
// Ref: https://msdn.microsoft.com/en-en/library/windows/desktop/ms680578(v=vs.85).aspx
14+
char info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
15+
SYMBOL_INFO* info = reinterpret_cast<SYMBOL_INFO*>(info_buf);
16+
char demangled[MAX_SYM_NAME];
17+
18+
for (int i = 1; i < size; i += 1) {
19+
void* frame = frames[i];
20+
fprintf(fp, "%2d: ", i);
21+
info->MaxNameLen = MAX_SYM_NAME;
22+
info->SizeOfStruct = sizeof(SYMBOL_INFO);
23+
const bool have_info =
24+
SymFromAddr(process, reinterpret_cast<DWORD64>(frame), nullptr, info);
25+
if (!have_info || strlen(info->Name) == 0) {
26+
fprintf(fp, "%p", frame);
27+
} else if (UnDecorateSymbolName(info->Name,
28+
demangled,
29+
sizeof(demangled),
30+
UNDNAME_COMPLETE)) {
31+
fprintf(fp, "%s", demangled);
32+
} else {
33+
fprintf(fp, "%s", info->Name);
34+
}
35+
fprintf(fp, "\n");
36+
}
37+
(void)SymCleanup(process);
638
}
739

840
} // namespace node

src/node.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@
4040
#endif
4141

4242
// This should be defined in make system.
43-
// See issue https://github.com/joyent/node/issues/1236
43+
// See issue https://github.com/nodejs/node-v0.x-archive/issues/1236
4444
#if defined(__MINGW32__) || defined(_MSC_VER)
4545
#ifndef _WIN32_WINNT
46-
# define _WIN32_WINNT 0x0501
46+
# define _WIN32_WINNT 0x0600 // Windows Server 2008
4747
#endif
4848

4949
#ifndef NOMINMAX

test/abort/test-abort-backtrace.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
'use strict';
22
const common = require('../common');
3-
if (common.isWindows)
4-
common.skip('Backtraces unimplemented on Windows.');
5-
63
const assert = require('assert');
74
const cp = require('child_process');
85

@@ -21,8 +18,10 @@ if (process.argv[2] === 'child') {
2118
assert.fail(`Each frame should start with a frame number:\n${stderr}`);
2219
}
2320

24-
if (!frames.some((frame) => frame.includes(`[${process.execPath}]`))) {
25-
assert.fail(`Some frames should include the binary name:\n${stderr}`);
21+
if (!common.isWindows) {
22+
if (!frames.some((frame) => frame.includes(`[${process.execPath}]`))) {
23+
assert.fail(`Some frames should include the binary name:\n${stderr}`);
24+
}
2625
}
2726
}
2827
}

0 commit comments

Comments
 (0)