@@ -100,35 +100,104 @@ class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext {
100
100
USE (SymInitialize (current_process_, nullptr , true ));
101
101
}
102
102
103
- ~Win32SymbolDebuggingContext () {
103
+ ~Win32SymbolDebuggingContext () override {
104
104
USE (SymCleanup (current_process_));
105
105
}
106
106
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
112
134
113
- info-> MaxNameLen = MAX_SYM_NAME ;
114
- info-> SizeOfStruct = sizeof (SYMBOL_INFO);
135
+ return NameAndDisplacement () ;
136
+ }
115
137
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
130
190
}
191
+ return nullptr ;
192
+ }
131
193
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
+ }
132
201
return ret;
133
202
}
134
203
@@ -145,6 +214,13 @@ class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext {
145
214
return CaptureStackBackTrace (0 , count, frames, nullptr );
146
215
}
147
216
217
+ Win32SymbolDebuggingContext (const Win32SymbolDebuggingContext&) = delete ;
218
+ Win32SymbolDebuggingContext (Win32SymbolDebuggingContext&&) = delete ;
219
+ Win32SymbolDebuggingContext operator =(const Win32SymbolDebuggingContext&)
220
+ = delete ;
221
+ Win32SymbolDebuggingContext operator =(Win32SymbolDebuggingContext&&)
222
+ = delete ;
223
+
148
224
private:
149
225
HANDLE current_process_;
150
226
};
@@ -158,13 +234,18 @@ NativeSymbolDebuggingContext::New() {
158
234
#endif // __POSIX__
159
235
160
236
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
+ }
162
242
if (!filename.empty ()) {
163
- ret += " [" ;
164
- ret += filename;
165
- ret += ' ]' ;
243
+ oss << " [" << filename << ' ]' ;
244
+ }
245
+ if (line != 0 ) {
246
+ oss << " :L" << line;
166
247
}
167
- return ret ;
248
+ return oss. str () ;
168
249
}
169
250
170
251
void DumpBacktrace (FILE* fp) {
@@ -173,8 +254,8 @@ void DumpBacktrace(FILE* fp) {
173
254
const int size = sym_ctx->GetStackTrace (frames, arraysize (frames));
174
255
for (int i = 1 ; i < size; i += 1 ) {
175
256
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 ());
178
259
}
179
260
}
180
261
0 commit comments