@@ -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
160236std::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
170251void 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
0 commit comments