summaryrefslogtreecommitdiff
path: root/src/common/extended_trace.cpp
diff options
context:
space:
mode:
authorGravatar archshift2015-02-18 22:30:31 -0800
committerGravatar archshift2015-02-18 22:30:31 -0800
commit9f7f1a227225c6dd5575e73a8d8891468940455c (patch)
tree08872754e481771c2b8d82bd304567a077f89b73 /src/common/extended_trace.cpp
parentRemove the useless msg_handler compilation unit that was left over from Dolphin (diff)
downloadyuzu-9f7f1a227225c6dd5575e73a8d8891468940455c.tar.gz
yuzu-9f7f1a227225c6dd5575e73a8d8891468940455c.tar.xz
yuzu-9f7f1a227225c6dd5575e73a8d8891468940455c.zip
Remove useless extended_trace compilation unit that was leftover from Dolphin
Diffstat (limited to 'src/common/extended_trace.cpp')
-rw-r--r--src/common/extended_trace.cpp428
1 files changed, 0 insertions, 428 deletions
diff --git a/src/common/extended_trace.cpp b/src/common/extended_trace.cpp
deleted file mode 100644
index cf7c346d4..000000000
--- a/src/common/extended_trace.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
1// --------------------------------------------------------------------------------------
2//
3// Written by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com
4// For companies(Austin,TX): If you would like to get my resume, send an email.
5//
6// The source is free, but if you want to use it, mention my name and e-mail address
7//
8// History:
9// 1.0 Initial version Zoltan Csizmadia
10// 1.1 WhineCube version Masken
11// 1.2 Dolphin version Masken
12//
13// --------------------------------------------------------------------------------------
14
15#if defined(WIN32)
16#include <cstdio>
17#include <windows.h>
18#include "common/extended_trace.h"
19#include "common/string_util.h"
20using namespace std;
21
22#include <tchar.h>
23#include <ImageHlp.h>
24
25#define BUFFERSIZE 0x200
26#pragma warning(disable:4996)
27
28// Unicode safe char* -> TCHAR* conversion
29void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut )
30{
31#if defined(UNICODE)||defined(_UNICODE)
32 ULONG index = 0;
33 PCSTR lpAct = lpszIn;
34
35 for( ; ; lpAct++ )
36 {
37 lpszOut[index++] = (TCHAR)(*lpAct);
38 if ( *lpAct == 0 )
39 break;
40 }
41#else
42 // This is trivial :)
43 strcpy( lpszOut, lpszIn );
44#endif
45}
46
47// Let's figure out the path for the symbol files
48// Search path= ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;" + lpszIniPath
49// Note: There is no size check for lpszSymbolPath!
50static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath )
51{
52 CHAR lpszPath[BUFFERSIZE];
53
54 // Creating the default path
55 // ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;"
56 strcpy( lpszSymbolPath, "." );
57
58 // environment variable _NT_SYMBOL_PATH
59 if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) )
60 {
61 strcat( lpszSymbolPath, ";" );
62 strcat( lpszSymbolPath, lpszPath );
63 }
64
65 // environment variable _NT_ALTERNATE_SYMBOL_PATH
66 if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) )
67 {
68 strcat( lpszSymbolPath, ";" );
69 strcat( lpszSymbolPath, lpszPath );
70 }
71
72 // environment variable SYSTEMROOT
73 if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) )
74 {
75 strcat( lpszSymbolPath, ";" );
76 strcat( lpszSymbolPath, lpszPath );
77 strcat( lpszSymbolPath, ";" );
78
79 // SYSTEMROOT\System32
80 strcat( lpszSymbolPath, lpszPath );
81 strcat( lpszSymbolPath, "\\System32" );
82 }
83
84 // Add user defined path
85 if ( lpszIniPath != nullptr )
86 if ( lpszIniPath[0] != '\0' )
87 {
88 strcat( lpszSymbolPath, ";" );
89 strcat( lpszSymbolPath, lpszIniPath );
90 }
91}
92
93// Uninitialize the loaded symbol files
94BOOL UninitSymInfo() {
95 return SymCleanup( GetCurrentProcess() );
96}
97
98// Initializes the symbol files
99BOOL InitSymInfo( PCSTR lpszInitialSymbolPath )
100{
101 CHAR lpszSymbolPath[BUFFERSIZE];
102 DWORD symOptions = SymGetOptions();
103
104 symOptions |= SYMOPT_LOAD_LINES;
105 symOptions &= ~SYMOPT_UNDNAME;
106 SymSetOptions( symOptions );
107 InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath );
108
109 return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE);
110}
111
112// Get the module name from a given address
113static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule )
114{
115 BOOL ret = FALSE;
116 IMAGEHLP_MODULE moduleInfo;
117
118 ::ZeroMemory( &moduleInfo, sizeof(moduleInfo) );
119 moduleInfo.SizeOfStruct = sizeof(moduleInfo);
120
121 if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) )
122 {
123 // Got it!
124 PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule );
125 ret = TRUE;
126 }
127 else
128 // Not found :(
129 _tcscpy( lpszModule, _T("?") );
130
131 return ret;
132}
133
134// Get function prototype and parameter info from ip address and stack address
135static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol )
136{
137 BOOL ret = FALSE;
138 DWORD dwSymSize = 10000;
139 TCHAR lpszUnDSymbol[BUFFERSIZE]=_T("?");
140 CHAR lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?";
141 LPTSTR lpszParamSep = nullptr;
142 LPTSTR lpszParsed = lpszUnDSymbol;
143 PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize );
144
145 ::ZeroMemory( pSym, dwSymSize );
146 pSym->SizeOfStruct = dwSymSize;
147 pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL);
148
149 // Set the default to unknown
150 _tcscpy( lpszSymbol, _T("?") );
151
152 // Get symbol info for IP
153#ifndef _M_X64
154 DWORD dwDisp = 0;
155 if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) )
156#else
157 //makes it compile but hell im not sure if this works...
158 DWORD64 dwDisp = 0;
159 if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) )
160#endif
161 {
162 // Make the symbol readable for humans
163 UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,
164 UNDNAME_COMPLETE |
165 UNDNAME_NO_THISTYPE |
166 UNDNAME_NO_SPECIAL_SYMS |
167 UNDNAME_NO_MEMBER_TYPE |
168 UNDNAME_NO_MS_KEYWORDS |
169 UNDNAME_NO_ACCESS_SPECIFIERS );
170
171 // Symbol information is ANSI string
172 PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol );
173
174 // I am just smarter than the symbol file :)
175 if (_tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0)
176 _tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)"));
177 else if (_tcscmp(lpszUnDSymbol, _T("_main")) == 0)
178 _tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)"));
179 else if (_tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0)
180 _tcscpy(lpszUnDSymbol, _T("mainCRTStartup()"));
181 else if (_tcscmp(lpszUnDSymbol, _T("_wmain")) == 0)
182 _tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)"));
183 else if (_tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0)
184 _tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()"));
185
186 lpszSymbol[0] = _T('\0');
187
188 // Let's go through the stack, and modify the function prototype, and insert the actual
189 // parameter values from the stack
190 if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == nullptr && _tcsstr( lpszUnDSymbol, _T("()") ) == nullptr)
191 {
192 ULONG index = 0;
193 for( ; ; index++ )
194 {
195 lpszParamSep = _tcschr( lpszParsed, _T(',') );
196 if ( lpszParamSep == nullptr )
197 break;
198
199 *lpszParamSep = _T('\0');
200
201 _tcscat( lpszSymbol, lpszParsed );
202 _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) );
203
204 lpszParsed = lpszParamSep + 1;
205 }
206
207 lpszParamSep = _tcschr( lpszParsed, _T(')') );
208 if ( lpszParamSep != nullptr )
209 {
210 *lpszParamSep = _T('\0');
211
212 _tcscat( lpszSymbol, lpszParsed );
213 _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) );
214
215 lpszParsed = lpszParamSep + 1;
216 }
217 }
218
219 _tcscat( lpszSymbol, lpszParsed );
220
221 ret = TRUE;
222 }
223 GlobalFree( pSym );
224
225 return ret;
226}
227
228// Get source file name and line number from IP address
229// The output format is: "sourcefile(linenumber)" or
230// "modulename!address" or
231// "address"
232static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo )
233{
234 BOOL ret = FALSE;
235 IMAGEHLP_LINE lineInfo;
236 DWORD dwDisp;
237 TCHAR lpszFileName[BUFFERSIZE] = _T("");
238 TCHAR lpModuleInfo[BUFFERSIZE] = _T("");
239
240 _tcscpy( lpszSourceInfo, _T("?(?)") );
241
242 ::ZeroMemory( &lineInfo, sizeof( lineInfo ) );
243 lineInfo.SizeOfStruct = sizeof( lineInfo );
244
245 if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) )
246 {
247 // Got it. Let's use "sourcefile(linenumber)" format
248 PCSTR2LPTSTR( lineInfo.FileName, lpszFileName );
249 TCHAR fname[_MAX_FNAME];
250 TCHAR ext[_MAX_EXT];
251 _tsplitpath(lpszFileName, nullptr, nullptr, fname, ext);
252 _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber );
253 ret = TRUE;
254 }
255 else
256 {
257 // There is no source file information. :(
258 // Let's use the "modulename!address" format
259 GetModuleNameFromAddress( address, lpModuleInfo );
260
261 if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0'))
262 // There is no modulename information. :((
263 // Let's use the "address" format
264 _stprintf( lpszSourceInfo, _T("0x%08X"), address );
265 else
266 _stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address );
267
268 ret = FALSE;
269 }
270
271 return ret;
272}
273
274void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack)
275{
276 TCHAR symInfo[BUFFERSIZE] = _T("?");
277 TCHAR srcInfo[BUFFERSIZE] = _T("?");
278
279 GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo);
280 GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo);
281 etfprint(file, " " + Common::TStrToUTF8(srcInfo) + " : " + Common::TStrToUTF8(symInfo) + "\n");
282}
283
284void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file )
285{
286 STACKFRAME callStack;
287 BOOL bResult;
288 CONTEXT context;
289 HANDLE hProcess = GetCurrentProcess();
290
291 // If it's not this thread, let's suspend it, and resume it at the end
292 if ( hThread != GetCurrentThread() )
293 if ( SuspendThread( hThread ) == -1 )
294 {
295 // whaaat ?!
296 etfprint(file, "Call stack info failed\n");
297 return;
298 }
299
300 ::ZeroMemory( &context, sizeof(context) );
301 context.ContextFlags = CONTEXT_FULL;
302
303 if ( !GetThreadContext( hThread, &context ) )
304 {
305 etfprint(file, "Call stack info failed\n");
306 return;
307 }
308
309 ::ZeroMemory( &callStack, sizeof(callStack) );
310#ifndef _M_X64
311 callStack.AddrPC.Offset = context.Eip;
312 callStack.AddrStack.Offset = context.Esp;
313 callStack.AddrFrame.Offset = context.Ebp;
314#else
315 callStack.AddrPC.Offset = context.Rip;
316 callStack.AddrStack.Offset = context.Rsp;
317 callStack.AddrFrame.Offset = context.Rbp;
318#endif
319 callStack.AddrPC.Mode = AddrModeFlat;
320 callStack.AddrStack.Mode = AddrModeFlat;
321 callStack.AddrFrame.Mode = AddrModeFlat;
322
323 etfprint(file, "Call stack info: \n");
324 etfprint(file, lpszMessage);
325
326 PrintFunctionAndSourceInfo(file, callStack);
327
328 for( ULONG index = 0; ; index++ )
329 {
330 bResult = StackWalk(
331 IMAGE_FILE_MACHINE_I386,
332 hProcess,
333 hThread,
334 &callStack,
335 nullptr,
336 nullptr,
337 SymFunctionTableAccess,
338 SymGetModuleBase,
339 nullptr);
340
341 if ( index == 0 )
342 continue;
343
344 if( !bResult || callStack.AddrFrame.Offset == 0 )
345 break;
346
347 PrintFunctionAndSourceInfo(file, callStack);
348
349 }
350
351 if ( hThread != GetCurrentThread() )
352 ResumeThread( hThread );
353}
354
355void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp )
356{
357 STACKFRAME callStack;
358 BOOL bResult;
359 TCHAR symInfo[BUFFERSIZE] = _T("?");
360 TCHAR srcInfo[BUFFERSIZE] = _T("?");
361 HANDLE hProcess = GetCurrentProcess();
362
363 // If it's not this thread, let's suspend it, and resume it at the end
364 if ( hThread != GetCurrentThread() )
365 if ( SuspendThread( hThread ) == -1 )
366 {
367 // whaaat ?!
368 etfprint(file, "Call stack info failed\n");
369 return;
370 }
371
372 ::ZeroMemory( &callStack, sizeof(callStack) );
373 callStack.AddrPC.Offset = eip;
374 callStack.AddrStack.Offset = esp;
375 callStack.AddrFrame.Offset = ebp;
376 callStack.AddrPC.Mode = AddrModeFlat;
377 callStack.AddrStack.Mode = AddrModeFlat;
378 callStack.AddrFrame.Mode = AddrModeFlat;
379
380 etfprint(file, "Call stack info: \n");
381 etfprint(file, lpszMessage);
382
383 PrintFunctionAndSourceInfo(file, callStack);
384
385 for( ULONG index = 0; ; index++ )
386 {
387 bResult = StackWalk(
388 IMAGE_FILE_MACHINE_I386,
389 hProcess,
390 hThread,
391 &callStack,
392 nullptr,
393 nullptr,
394 SymFunctionTableAccess,
395 SymGetModuleBase,
396 nullptr);
397
398 if ( index == 0 )
399 continue;
400
401 if( !bResult || callStack.AddrFrame.Offset == 0 )
402 break;
403
404 PrintFunctionAndSourceInfo(file, callStack);
405 }
406
407 if ( hThread != GetCurrentThread() )
408 ResumeThread( hThread );
409}
410
411char g_uefbuf[2048];
412
413void etfprintf(FILE *file, const char *format, ...)
414{
415 va_list ap;
416 va_start(ap, format);
417 int len = vsprintf(g_uefbuf, format, ap);
418 fwrite(g_uefbuf, 1, len, file);
419 va_end(ap);
420}
421
422void etfprint(FILE *file, const std::string &text)
423{
424 size_t len = text.length();
425 fwrite(text.data(), 1, len, file);
426}
427
428#endif //WIN32