src: implement backtrace-on-abort for windows

PR-URL: https://github.com/nodejs/node/pull/16951
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
Anna Henningsen 2017-11-11 14:42:17 +01:00
parent 3eb5778d1b
commit 7d8fe7df91
No known key found for this signature in database
GPG Key ID: 9C63F3A6CD2AD8F9
3 changed files with 39 additions and 8 deletions

View File

@ -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

View File

@ -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

View File

@ -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');
@ -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}`);
}
}
}
}