Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c32cf17

Browse filesBrowse files
refackMylesBorins
authored andcommitted
src,win: informative stack traces
Refresh `Win32SymbolDebuggingContext::LookupSymbol` to use more APIs PR-URL: #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>
1 parent 4a52fc0 commit c32cf17
Copy full SHA for c32cf17

File tree

Expand file treeCollapse file tree

2 files changed

+123
-30
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+123
-30
lines changed
Open diff view settings
Collapse file

‎src/debug_utils.cc‎

Copy file name to clipboardExpand all lines: src/debug_utils.cc
+110-29Lines changed: 110 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -100,35 +100,104 @@ class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext {
100100
USE(SymInitialize(current_process_, nullptr, true));
101101
}
102102

103-
~Win32SymbolDebuggingContext() {
103+
~Win32SymbolDebuggingContext() override {
104104
USE(SymCleanup(current_process_));
105105
}
106106

107-
SymbolInfo LookupSymbol(void* address) override {
108-
// Ref: https://msdn.microsoft.com/en-en/library/windows/desktop/ms680578(v=vs.85).aspx
109-
char info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
110-
SYMBOL_INFO* info = reinterpret_cast<SYMBOL_INFO*>(info_buf);
111-
char demangled[MAX_SYM_NAME];
107+
using NameAndDisplacement = std::pair<std::string, DWORD64>;
108+
NameAndDisplacement WrappedSymFromAddr(DWORD64 dwAddress) const {
109+
// Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address
110+
// Patches:
111+
// Use `fprintf(stderr, ` instead of `printf`
112+
// `sym.filename = pSymbol->Name` on success
113+
// `current_process_` instead of `hProcess.
114+
DWORD64 dwDisplacement = 0;
115+
// Patch: made into arg - DWORD64 dwAddress = SOME_ADDRESS;
116+
117+
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
118+
const auto pSymbol = reinterpret_cast<PSYMBOL_INFO>(buffer);
119+
120+
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
121+
pSymbol->MaxNameLen = MAX_SYM_NAME;
122+
123+
if (SymFromAddr(current_process_, dwAddress, &dwDisplacement, pSymbol)) {
124+
// SymFromAddr returned success
125+
return NameAndDisplacement(pSymbol->Name, dwDisplacement);
126+
} else {
127+
// SymFromAddr failed
128+
const DWORD error = GetLastError(); // "eat" the error anyway
129+
#ifdef DEBUG
130+
fprintf(stderr, "SymFromAddr returned error : %lu\n", error);
131+
#endif
132+
}
133+
// End MSDN code
112134

113-
info->MaxNameLen = MAX_SYM_NAME;
114-
info->SizeOfStruct = sizeof(SYMBOL_INFO);
135+
return NameAndDisplacement();
136+
}
115137

116-
SymbolInfo ret;
117-
const bool have_info = SymFromAddr(current_process_,
118-
reinterpret_cast<DWORD64>(address),
119-
nullptr,
120-
info);
121-
if (have_info && strlen(info->Name) == 0) {
122-
if (UnDecorateSymbolName(info->Name,
123-
demangled,
124-
sizeof(demangled),
125-
UNDNAME_COMPLETE)) {
126-
ret.name = demangled;
127-
} else {
128-
ret.name = info->Name;
129-
}
138+
SymbolInfo WrappedGetLine(DWORD64 dwAddress) const {
139+
SymbolInfo sym{};
140+
141+
// Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address
142+
// Patches:
143+
// Use `fprintf(stderr, ` instead of `printf`.
144+
// Assign values to `sym` on success.
145+
// `current_process_` instead of `hProcess.
146+
147+
// Patch: made into arg - DWORD64 dwAddress;
148+
DWORD dwDisplacement;
149+
IMAGEHLP_LINE64 line;
150+
151+
SymSetOptions(SYMOPT_LOAD_LINES);
152+
153+
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
154+
// Patch: made into arg - dwAddress = 0x1000000;
155+
156+
if (SymGetLineFromAddr64(current_process_, dwAddress,
157+
&dwDisplacement, &line)) {
158+
// SymGetLineFromAddr64 returned success
159+
sym.filename = line.FileName;
160+
sym.line = line.LineNumber;
161+
} else {
162+
// SymGetLineFromAddr64 failed
163+
const DWORD error = GetLastError(); // "eat" the error anyway
164+
#ifdef DEBUG
165+
fprintf(stderr, "SymGetLineFromAddr64 returned error : %lu\n", error);
166+
#endif
167+
}
168+
// End MSDN code
169+
170+
return sym;
171+
}
172+
173+
// Fills the SymbolInfo::name of the io/out argument `sym`
174+
std::string WrappedUnDecorateSymbolName(const char* name) const {
175+
// Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-undecorated-symbol-names
176+
// Patches:
177+
// Use `fprintf(stderr, ` instead of `printf`.
178+
// return `szUndName` instead of `printf` on success
179+
char szUndName[MAX_SYM_NAME];
180+
if (UnDecorateSymbolName(name, szUndName, sizeof(szUndName),
181+
UNDNAME_COMPLETE)) {
182+
// UnDecorateSymbolName returned success
183+
return szUndName;
184+
} else {
185+
// UnDecorateSymbolName failed
186+
const DWORD error = GetLastError(); // "eat" the error anyway
187+
#ifdef DEBUG
188+
fprintf(stderr, "UnDecorateSymbolName returned error %lu\n", error);
189+
#endif
130190
}
191+
return nullptr;
192+
}
131193

194+
SymbolInfo LookupSymbol(void* address) override {
195+
const DWORD64 dw_address = reinterpret_cast<DWORD64>(address);
196+
SymbolInfo ret = WrappedGetLine(dw_address);
197+
std::tie(ret.name, ret.dis) = WrappedSymFromAddr(dw_address);
198+
if (!ret.name.empty()) {
199+
ret.name = WrappedUnDecorateSymbolName(ret.name.c_str());
200+
}
132201
return ret;
133202
}
134203

@@ -145,6 +214,13 @@ class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext {
145214
return CaptureStackBackTrace(0, count, frames, nullptr);
146215
}
147216

217+
Win32SymbolDebuggingContext(const Win32SymbolDebuggingContext&) = delete;
218+
Win32SymbolDebuggingContext(Win32SymbolDebuggingContext&&) = delete;
219+
Win32SymbolDebuggingContext operator=(const Win32SymbolDebuggingContext&)
220+
= delete;
221+
Win32SymbolDebuggingContext operator=(Win32SymbolDebuggingContext&&)
222+
= delete;
223+
148224
private:
149225
HANDLE current_process_;
150226
};
@@ -158,13 +234,18 @@ NativeSymbolDebuggingContext::New() {
158234
#endif // __POSIX__
159235

160236
std::string NativeSymbolDebuggingContext::SymbolInfo::Display() const {
161-
std::string ret = name;
237+
std::ostringstream oss;
238+
oss << name;
239+
if (dis != 0) {
240+
oss << "+" << dis;
241+
}
162242
if (!filename.empty()) {
163-
ret += " [";
164-
ret += filename;
165-
ret += ']';
243+
oss << " [" << filename << ']';
244+
}
245+
if (line != 0) {
246+
oss << ":L" << line;
166247
}
167-
return ret;
248+
return oss.str();
168249
}
169250

170251
void DumpBacktrace(FILE* fp) {
@@ -173,8 +254,8 @@ void DumpBacktrace(FILE* fp) {
173254
const int size = sym_ctx->GetStackTrace(frames, arraysize(frames));
174255
for (int i = 1; i < size; i += 1) {
175256
void* frame = frames[i];
176-
fprintf(fp, "%2d: %p %s\n",
177-
i, frame, sym_ctx->LookupSymbol(frame).Display().c_str());
257+
NativeSymbolDebuggingContext::SymbolInfo s = sym_ctx->LookupSymbol(frame);
258+
fprintf(fp, "%2d: %p %s\n", i, frame, s.Display().c_str());
178259
}
179260
}
180261

Collapse file

‎src/debug_utils.h‎

Copy file name to clipboardExpand all lines: src/debug_utils.h
+13-1Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "async_wrap.h"
77
#include "env.h"
88
#include <string>
9+
#include <sstream>
910

1011
// Use FORCE_INLINE on functions that have a debug-category-enabled check first
1112
// and then ideally only a single function call following it, to maintain
@@ -93,14 +94,25 @@ class NativeSymbolDebuggingContext {
9394
public:
9495
std::string name;
9596
std::string filename;
97+
size_t line = 0;
98+
size_t dis = 0;
9699

97100
std::string Display() const;
98101
};
99102

103+
NativeSymbolDebuggingContext() = default;
100104
virtual ~NativeSymbolDebuggingContext() {}
101-
virtual SymbolInfo LookupSymbol(void* address) { return { "", "" }; }
105+
106+
virtual SymbolInfo LookupSymbol(void* address) { return {}; }
102107
virtual bool IsMapped(void* address) { return false; }
103108
virtual int GetStackTrace(void** frames, int count) { return 0; }
109+
110+
NativeSymbolDebuggingContext(const NativeSymbolDebuggingContext&) = delete;
111+
NativeSymbolDebuggingContext(NativeSymbolDebuggingContext&&) = delete;
112+
NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&)
113+
= delete;
114+
NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&&)
115+
= delete;
104116
};
105117

106118
// Variant of `uv_loop_close` that tries to be as helpful as possible

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.