From 7db8f01ef7b08ca6a7f34898431c54744cd86f43 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 11 Nov 2017 14:42:17 +0100 Subject: [PATCH] src: implement backtrace-on-abort for windows PR-URL: https://github.com/nodejs/node/pull/16951 Reviewed-By: Refael Ackermann Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- src/backtrace_win32.cc | 34 +++++++++++++++++++++++++++++- src/node.h | 4 ++-- test/abort/test-abort-backtrace.js | 9 ++++---- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/backtrace_win32.cc b/src/backtrace_win32.cc index 71610fd663bb3c..ccc3af9455b18d 100644 --- a/src/backtrace_win32.cc +++ b/src/backtrace_win32.cc @@ -1,8 +1,40 @@ -#include "node.h" +#include "node_internals.h" +#include +#include 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(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(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 diff --git a/src/node.h b/src/node.h index 667807df1eefce..66211c7502ff98 100644 --- a/src/node.h +++ b/src/node.h @@ -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 diff --git a/test/abort/test-abort-backtrace.js b/test/abort/test-abort-backtrace.js index 6d3121e538eb02..e69ac3ddfdece8 100644 --- a/test/abort/test-abort-backtrace.js +++ b/test/abort/test-abort-backtrace.js @@ -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}`); + } } } }