15 #pragma warning( disable : 4091 ) // unused typedef 16 #include "../../lib/StackWalker/StackWalker.h" 24 #define DECLSPEC_DEPRECATED 27 #include "C:\\Program Files\\Microsoft Visual Studio\\PlatformSDK\\include\\dbghelp.h" 34 #pragma warning( disable : 4100 ) // TODO: This file needs some serious rewrite, so I'm just 46 typedef BOOL( WINAPI* __SymFromAddr )( _In_ HANDLE hProcess, _In_ DWORD64
Address,
48 _Inout_ PSYMBOL_INFO
Symbol );
49 typedef DWORD( WINAPI* __SymGetOptions )( VOID );
50 typedef DWORD( WINAPI* __SymSetOptions )( _In_
DWORD SymOptions );
51 typedef BOOL( WINAPI* __SymGetLineFromAddr64 )( _In_ HANDLE hProcess, _In_ DWORD64
qwAddr,
53 _Out_ PIMAGEHLP_LINE64
Line64 );
82 assert( !_Initialized );
86 strftime( _StartTimestamp,
sizeof _StartTimestamp,
"%Y%m%d%H%M%S", &time_tm );
98 char szDbgHelpPath[_MAX_PATH];
99 char* szResult = NULL;
101 if ( GetModuleFileName( NULL, szDbgHelpPath, _MAX_PATH ) )
103 char* pSlash = strchr( szDbgHelpPath,
'\\' );
106 strcpy( pSlash + 1,
"DBGHELP.DLL" );
107 hDbgHelpDll = ::LoadLibrary( szDbgHelpPath );
111 if ( hDbgHelpDll == NULL )
114 hDbgHelpDll = ::LoadLibrary(
"DBGHELP.DLL" );
118 MINIDUMPWRITEDUMP pDump =
119 ( MINIDUMPWRITEDUMP )::GetProcAddress( hDbgHelpDll,
"MiniDumpWriteDump" );
121 ::SetUnhandledExceptionFilter( TopLevelFilter );
123 szResult =
"Warning: DBGHELP.DLL too old, version 5.1+ required.";
126 szResult =
"Warning: DBGHELP.DLL not found, version 5.1+ required in POL directory.";
138 LONG retval = EXCEPTION_CONTINUE_SEARCH;
140 fmt::Writer dumppath;
144 MINIDUMPWRITEDUMP pDump =
145 ( MINIDUMPWRITEDUMP )::GetProcAddress( hDbgHelpDll,
"MiniDumpWriteDump" );
148 dumppath << _StartTimestamp <<
"-" << fmt::hex( _DumpCount++ ) <<
".dmp";
150 HANDLE
hFile = ::CreateFile( dumppath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
151 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
153 if ( hFile != INVALID_HANDLE_VALUE )
155 _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
157 ExInfo.ThreadId = ::GetCurrentThreadId();
158 ExInfo.ExceptionPointers = pExceptionInfo;
159 ExInfo.ClientPointers = NULL;
162 MINIDUMP_TYPE dumptype;
163 if ( _MiniDumpType ==
"large" )
164 dumptype = MiniDumpWithFullMemory;
165 else if ( _MiniDumpType ==
"variable" )
166 dumptype = MiniDumpWithDataSegs;
168 dumptype = MiniDumpNormal;
170 ERROR_PRINT <<
"Unhandled Exception! Minidump started...\n";
172 pDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, dumptype, &ExInfo, NULL, NULL );
176 "Unhandled Exception! Writing Minidump file. \nPost this file with explanation and " 177 "last lines from log files on http://forums.polserver.com/tracker.php for the " 178 "development team.\nSaved dump file to '{}'\n" )
180 retval = EXCEPTION_EXECUTE_HANDLER;
184 result.Format(
"Failed to save dump file to '{}' (error {})" )
185 << dumppath.str() << GetLastError();
187 ::CloseHandle( hFile );
191 result.Format(
"Failed to create dump file '{}' (error {})" )
192 << dumppath.str() << GetLastError();
196 FreeLibrary( hDbgHelpDll );
197 _Initialized =
false;
199 if ( result.size() > 0 )
201 POLLOG_ERROR <<
"##########################################################\n" 202 << result.str() <<
"\n" 204 <<
"\n##########################################################\n";
218 if ( _log.size() > 0 )
227 LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion )
POL_OVERRIDE 236 if ( ( eType != lastEntry ) && ( entry.offset != 0 ) )
238 if ( entry.undFullName[0] != 0 )
239 _log << entry.undFullName;
240 else if ( entry.undName[0] != 0 )
241 _log << entry.undName;
243 _log <<
"(function-name not available)";
244 _log.Format(
" - {:p}\n" ) << (LPVOID)entry.offset;
246 if ( entry.lineFileName[0] == 0 )
248 _log <<
" (filename not available)\n";
252 _log <<
" " << entry.lineFileName <<
" : " << entry.lineNumber <<
"\n";
256 catch ( std::exception& e )
258 POLLOG_ERROR <<
"failed to format backtrace " << e.what() <<
"\n";
268 <<
"\n##########################################################\nCurrent StackBackTrace\n";
283 sw.
_log <<
"##########################################################\n";
DWORD HANDLE MINIDUMP_TYPE DumpType
DWORD HANDLE MINIDUMP_TYPE CONST PMINIDUMP_EXCEPTION_INFORMATION CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam
_In_opt_ PCSTR _In_ BOOL fInvadeProcess
_In_opt_ PCSTR UserSearchPath
std::string scripts_thread_script
static unsigned _DumpCount
_In_ DWORD64 _Out_opt_ PDWORD64 Displacement
static char _StartTimestamp[32]
std::tm localtime(const std::time_t &t)
threadsafe version of localtime
static LONG WINAPI TopLevelFilter(struct _EXCEPTION_POINTERS *pExceptionInfo)
typedef DWORD(WINAPI *__SymGetOptions)(VOID)
virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion) POL_OVERRIDE
StackWalkerLogger(int options)
DWORD HANDLE MINIDUMP_TYPE CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam
virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) POL_OVERRIDE
static void SetMiniDumpType(const std::string &dumptype)
void wait_for_empty_queue()
static std::string _MiniDumpType
_In_ DWORD64 _Out_ PDWORD _Out_ PIMAGEHLP_LINE64 Line64
typedef BOOL(WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess
virtual ~StackWalkerLogger()
DWORD HANDLE MINIDUMP_TYPE CONST PMINIDUMP_EXCEPTION_INFORMATION CONST PMINIDUMP_USER_STREAM_INFORMATION CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam
void InstallOldStructuredExceptionHandler(void)
virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) POL_OVERRIDE
_In_ DWORD64 _Out_opt_ PDWORD64 _Inout_ PSYMBOL_INFO Symbol
_In_ DWORD64 _Out_ PDWORD pdwDisplacement
virtual void OnOutput(LPCSTR szText) POL_OVERRIDE
virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) POL_OVERRIDE
LogFacility * global_logger
unsigned scripts_thread_scriptPC
static void print_backtrace()