diff options
author | Refael Ackermann <refack@gmail.com> | 2018-10-22 15:07:00 -0400 |
---|---|---|
committer | Refael Ackermann <refack@gmail.com> | 2018-10-29 21:44:17 -0400 |
commit | 247b513059592cbfe9ec3012aa9bc461b9899c7f (patch) | |
tree | 946e1fb800fff4bca98a6c6732dbc3e408dba03e /src/debug_utils.cc | |
parent | f90cf19fdd729cff6147b12be191effa6113712e (diff) | |
download | android-node-v8-247b513059592cbfe9ec3012aa9bc461b9899c7f.tar.gz android-node-v8-247b513059592cbfe9ec3012aa9bc461b9899c7f.tar.bz2 android-node-v8-247b513059592cbfe9ec3012aa9bc461b9899c7f.zip |
src,win: informative stack traces
Refresh `Win32SymbolDebuggingContext::LookupSymbol` to use more APIs
PR-URL: https://github.com/nodejs/node/pull/23822
Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address
Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-undecorated-symbol-names
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Diffstat (limited to 'src/debug_utils.cc')
-rw-r--r-- | src/debug_utils.cc | 139 |
1 files changed, 110 insertions, 29 deletions
diff --git a/src/debug_utils.cc b/src/debug_utils.cc index a24c51de39..77ea219bfc 100644 --- a/src/debug_utils.cc +++ b/src/debug_utils.cc @@ -100,35 +100,104 @@ class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext { USE(SymInitialize(current_process_, nullptr, true)); } - ~Win32SymbolDebuggingContext() { + ~Win32SymbolDebuggingContext() override { USE(SymCleanup(current_process_)); } - SymbolInfo LookupSymbol(void* address) override { - // 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]; + using NameAndDisplacement = std::pair<std::string, DWORD64>; + NameAndDisplacement WrappedSymFromAddr(DWORD64 dwAddress) const { + // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address + // Patches: + // Use `fprintf(stderr, ` instead of `printf` + // `sym.filename = pSymbol->Name` on success + // `current_process_` instead of `hProcess. + DWORD64 dwDisplacement = 0; + // Patch: made into arg - DWORD64 dwAddress = SOME_ADDRESS; + + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; + const auto pSymbol = reinterpret_cast<PSYMBOL_INFO>(buffer); + + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = MAX_SYM_NAME; + + if (SymFromAddr(current_process_, dwAddress, &dwDisplacement, pSymbol)) { + // SymFromAddr returned success + return NameAndDisplacement(pSymbol->Name, dwDisplacement); + } else { + // SymFromAddr failed + const DWORD error = GetLastError(); // "eat" the error anyway +#ifdef DEBUG + fprintf(stderr, "SymFromAddr returned error : %lu\n", error); +#endif + } + // End MSDN code - info->MaxNameLen = MAX_SYM_NAME; - info->SizeOfStruct = sizeof(SYMBOL_INFO); + return NameAndDisplacement(); + } - SymbolInfo ret; - const bool have_info = SymFromAddr(current_process_, - reinterpret_cast<DWORD64>(address), - nullptr, - info); - if (have_info && strlen(info->Name) == 0) { - if (UnDecorateSymbolName(info->Name, - demangled, - sizeof(demangled), - UNDNAME_COMPLETE)) { - ret.name = demangled; - } else { - ret.name = info->Name; - } + SymbolInfo WrappedGetLine(DWORD64 dwAddress) const { + SymbolInfo sym{}; + + // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address + // Patches: + // Use `fprintf(stderr, ` instead of `printf`. + // Assign values to `sym` on success. + // `current_process_` instead of `hProcess. + + // Patch: made into arg - DWORD64 dwAddress; + DWORD dwDisplacement; + IMAGEHLP_LINE64 line; + + SymSetOptions(SYMOPT_LOAD_LINES); + + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + // Patch: made into arg - dwAddress = 0x1000000; + + if (SymGetLineFromAddr64(current_process_, dwAddress, + &dwDisplacement, &line)) { + // SymGetLineFromAddr64 returned success + sym.filename = line.FileName; + sym.line = line.LineNumber; + } else { + // SymGetLineFromAddr64 failed + const DWORD error = GetLastError(); // "eat" the error anyway +#ifdef DEBUG + fprintf(stderr, "SymGetLineFromAddr64 returned error : %lu\n", error); +#endif + } + // End MSDN code + + return sym; + } + + // Fills the SymbolInfo::name of the io/out argument `sym` + std::string WrappedUnDecorateSymbolName(const char* name) const { + // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-undecorated-symbol-names + // Patches: + // Use `fprintf(stderr, ` instead of `printf`. + // return `szUndName` instead of `printf` on success + char szUndName[MAX_SYM_NAME]; + if (UnDecorateSymbolName(name, szUndName, sizeof(szUndName), + UNDNAME_COMPLETE)) { + // UnDecorateSymbolName returned success + return szUndName; + } else { + // UnDecorateSymbolName failed + const DWORD error = GetLastError(); // "eat" the error anyway +#ifdef DEBUG + fprintf(stderr, "UnDecorateSymbolName returned error %lu\n", error); +#endif } + return nullptr; + } + SymbolInfo LookupSymbol(void* address) override { + const DWORD64 dw_address = reinterpret_cast<DWORD64>(address); + SymbolInfo ret = WrappedGetLine(dw_address); + std::tie(ret.name, ret.dis) = WrappedSymFromAddr(dw_address); + if (!ret.name.empty()) { + ret.name = WrappedUnDecorateSymbolName(ret.name.c_str()); + } return ret; } @@ -145,6 +214,13 @@ class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext { return CaptureStackBackTrace(0, count, frames, nullptr); } + Win32SymbolDebuggingContext(const Win32SymbolDebuggingContext&) = delete; + Win32SymbolDebuggingContext(Win32SymbolDebuggingContext&&) = delete; + Win32SymbolDebuggingContext operator=(const Win32SymbolDebuggingContext&) + = delete; + Win32SymbolDebuggingContext operator=(Win32SymbolDebuggingContext&&) + = delete; + private: HANDLE current_process_; }; @@ -158,13 +234,18 @@ NativeSymbolDebuggingContext::New() { #endif // __POSIX__ std::string NativeSymbolDebuggingContext::SymbolInfo::Display() const { - std::string ret = name; + std::ostringstream oss; + oss << name; + if (dis != 0) { + oss << "+" << dis; + } if (!filename.empty()) { - ret += " ["; - ret += filename; - ret += ']'; + oss << " [" << filename << ']'; + } + if (line != 0) { + oss << ":L" << line; } - return ret; + return oss.str(); } void DumpBacktrace(FILE* fp) { @@ -173,8 +254,8 @@ void DumpBacktrace(FILE* fp) { const int size = sym_ctx->GetStackTrace(frames, arraysize(frames)); for (int i = 1; i < size; i += 1) { void* frame = frames[i]; - fprintf(fp, "%2d: %p %s\n", - i, frame, sym_ctx->LookupSymbol(frame).Display().c_str()); + NativeSymbolDebuggingContext::SymbolInfo s = sym_ctx->LookupSymbol(frame); + fprintf(fp, "%2d: %p %s\n", i, frame, s.Display().c_str()); } } |