Skip to content

Commit

Permalink
src: implement backtrace-on-abort for windows
Browse files Browse the repository at this point in the history
PR-URL: #16951
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
  • Loading branch information
addaleax authored and MylesBorins committed Dec 11, 2017
1 parent a6b6acb commit 6f805c6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 8 deletions.
34 changes: 33 additions & 1 deletion src/backtrace_win32.cc
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
#include "node.h"
#include "node_internals.h"
#include <windows.h>
#include <dbghelp.h>

namespace node {

void DumpBacktrace(FILE* fp) {
void* frames[256];
int size = CaptureStackBackTrace(0, arraysize(frames), frames, nullptr);
HANDLE process = GetCurrentProcess();
(void)SymInitialize(process, nullptr, true);

// Ref: https://msdn.microsoft.com/en-en/library/windows/desktop/ms680578(v=vs.85).aspx
char info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
SYMBOL_INFO* info = reinterpret_cast<SYMBOL_INFO*>(info_buf);
char demangled[MAX_SYM_NAME];

for (int i = 1; i < size; i += 1) {
void* frame = frames[i];
fprintf(fp, "%2d: ", i);
info->MaxNameLen = MAX_SYM_NAME;
info->SizeOfStruct = sizeof(SYMBOL_INFO);
const bool have_info =
SymFromAddr(process, reinterpret_cast<DWORD64>(frame), nullptr, info);
if (!have_info || strlen(info->Name) == 0) {
fprintf(fp, "%p", frame);
} else if (UnDecorateSymbolName(info->Name,
demangled,
sizeof(demangled),
UNDNAME_COMPLETE)) {
fprintf(fp, "%s", demangled);
} else {
fprintf(fp, "%s", info->Name);
}
fprintf(fp, "\n");
}
(void)SymCleanup(process);
}

} // namespace node
4 changes: 2 additions & 2 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
#endif

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

#ifndef NOMINMAX
Expand Down
9 changes: 4 additions & 5 deletions test/abort/test-abort-backtrace.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
'use strict';
const common = require('../common');
if (common.isWindows)
common.skip('Backtraces unimplemented on Windows.');

const assert = require('assert');
const cp = require('child_process');

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

if (!frames.some((frame) => frame.includes(`[${process.execPath}]`))) {
assert.fail(`Some frames should include the binary name:\n${stderr}`);
if (!common.isWindows) {
if (!frames.some((frame) => frame.includes(`[${process.execPath}]`))) {
assert.fail(`Some frames should include the binary name:\n${stderr}`);
}
}
}
}

0 comments on commit 6f805c6

Please sign in to comment.