diff --git a/engine/common/crashhandler.c b/engine/common/crashhandler.c index 525237c3..f8cbc542 100644 --- a/engine/common/crashhandler.c +++ b/engine/common/crashhandler.c @@ -24,9 +24,11 @@ Crash handler, called from system ================ */ #if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP || XASH_CRASHHANDLER == CRASHHANDLER_WIN32 + #if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP + #pragma comment( lib, "dbghelp" ) -#pragma comment( lib, "psapi" ) + #include #include #include @@ -35,7 +37,7 @@ Crash handler, called from system typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; #endif -int ModuleName( HANDLE process, char *name, void *address, int len ) +static int Sys_ModuleName( HANDLE process, char *name, void *address, int len ) { DWORD_PTR baseAddress = 0; static HMODULE *moduleArray; @@ -44,27 +46,24 @@ int ModuleName( HANDLE process, char *name, void *address, int len ) DWORD bytesRequired; int i; - if(len < 3) + if( len < 3 ) return 0; - if ( !moduleArray && EnumProcessModules( process, NULL, 0, &bytesRequired ) ) + if( !moduleArray && EnumProcessModules( process, NULL, 0, &bytesRequired ) ) { if ( bytesRequired ) { moduleArrayBytes = (LPBYTE)LocalAlloc( LPTR, bytesRequired ); - if ( moduleArrayBytes ) + if( moduleArrayBytes && EnumProcessModules( process, (HMODULE *)moduleArrayBytes, bytesRequired, &bytesRequired ) ) { - if( EnumProcessModules( process, (HMODULE *)moduleArrayBytes, bytesRequired, &bytesRequired ) ) - { - moduleCount = bytesRequired / sizeof( HMODULE ); - moduleArray = (HMODULE *)moduleArrayBytes; - } + moduleCount = bytesRequired / sizeof( HMODULE ); + moduleArray = (HMODULE *)moduleArrayBytes; } } } - for( i = 0; iContextRecord, sizeof(CONTEXT) ); + memcpy( &context, pInfo->ContextRecord, sizeof( CONTEXT )); + options = SymGetOptions(); options |= SYMOPT_DEBUG; options |= SYMOPT_LOAD_LINES; @@ -97,9 +98,7 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo ) SymInitialize( process, NULL, TRUE ); - - - ZeroMemory( &stackframe, sizeof(STACKFRAME64) ); + ZeroMemory( &stackframe, sizeof( STACKFRAME64 )); #ifdef _M_IX86 image = IMAGE_FILE_MACHINE_I386; @@ -127,19 +126,25 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo ) stackframe.AddrBStore.Mode = AddrModeFlat; stackframe.AddrStack.Offset = context.IntSp; stackframe.AddrStack.Mode = AddrModeFlat; +#elif +#error #endif - len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n", pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode ); + len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n", + pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode ); if( SymGetLineFromAddr64( process, (DWORD64)pInfo->ExceptionRecord->ExceptionAddress, &dline, &line ) ) { - len += Q_snprintf(message + len, 1024 - len,"Exception: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline); + len += Q_snprintf(message + len, 1024 - len, "Exception: %s:%d:%d\n", + (char*)line.FileName, (int)line.LineNumber, (int)dline); } if( SymGetLineFromAddr64( process, stackframe.AddrPC.Offset, &dline, &line ) ) { - len += Q_snprintf(message + len, 1024 - len,"PC: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline); + len += Q_snprintf(message + len, 1024 - len,"PC: %s:%d:%d\n", + (char*)line.FileName, (int)line.LineNumber, (int)dline); } if( SymGetLineFromAddr64( process, stackframe.AddrFrame.Offset, &dline, &line ) ) { - len += Q_snprintf(message + len, 1024 - len,"Frame: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline); + len += Q_snprintf(message + len, 1024 - len,"Frame: %s:%d:%d\n", + (char*)line.FileName, (int)line.LineNumber, (int)dline); } for( i = 0; i < 25; i++ ) { @@ -149,39 +154,43 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo ) image, process, thread, &stackframe, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL); - DWORD64 displacement = 0; + if( !result ) break; - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); symbol->MaxNameLen = MAX_SYM_NAME; - len += Q_snprintf( message + len, 1024 - len, "% 2d %p", i, (void*)stackframe.AddrPC.Offset ); + len += Q_snprintf( message + len, 1024 - len, "% 2d %p", + i, (void*)stackframe.AddrPC.Offset ); if( SymFromAddr( process, stackframe.AddrPC.Offset, &displacement, symbol ) ) { len += Q_snprintf( message + len, 1024 - len, " %s ", symbol->Name ); } if( SymGetLineFromAddr64( process, stackframe.AddrPC.Offset, &dline, &line ) ) { - len += Q_snprintf(message + len, 1024 - len,"(%s:%d:%d) ", (char*)line.FileName, (int)line.LineNumber, (int)dline); + len += Q_snprintf(message + len, 1024 - len,"(%s:%d:%d) ", + (char*)line.FileName, (int)line.LineNumber, (int)dline); } len += Q_snprintf( message + len, 1024 - len, "("); - len += ModuleName( process, message + len, (void*)stackframe.AddrPC.Offset, 1024 - len ); + len += Sys_ModuleName( process, message + len, (void*)stackframe.AddrPC.Offset, 1024 - len ); len += Q_snprintf( message + len, 1024 - len, ")\n"); } -#ifdef XASH_SDL + +#if XASH_SDL >= 2 if( host.type != HOST_DEDICATED ) // let system to restart server automaticly - SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR,"Sys_Crash", message, host.hWnd ); + SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Sys_Crash", message, host.hWnd ); #endif - Sys_PrintLog(message); - SymCleanup(process); + Sys_PrintLog( message ); + + SymCleanup( process ); } -#endif //DBGHELP +#endif /* XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP */ + LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; -long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo ) +static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo ) { // save config if( host.status != HOST_CRASHED ) @@ -190,7 +199,7 @@ long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo ) host.crashed = true; #if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP - stack_trace( pInfo ); + Sys_StackTrace( pInfo ); #else Sys_Warn( "Sys_Crash: call %p at address %p", pInfo->ExceptionRecord->ExceptionAddress, pInfo->ExceptionRecord->ExceptionCode ); #endif @@ -233,13 +242,14 @@ void Sys_RestoreCrashHandler( void ) #include "library.h" -#if XASH_FREEBSD || XASH_NETBSD || XASH_ANDROID || XASH_LINUX +#if XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX #define HAVE_UCONTEXT_H 1 #endif #ifdef HAVE_UCONTEXT_H #include #endif + #include #include @@ -261,7 +271,7 @@ static int d_dladdr( void *sym, Dl_info *info ) #define dladdr d_dladdr #endif -int printframe( char *buf, int len, int i, void *addr ) +static int Sys_PrintFrame( char *buf, int len, int i, void *addr ) { Dl_info dlinfo; if( len <= 0 ) @@ -271,7 +281,7 @@ int printframe( char *buf, int len, int i, void *addr ) { if( dlinfo.dli_sname ) return Q_snprintf( buf, len, "%2d: %p <%s+%lu> (%s)\n", i, addr, dlinfo.dli_sname, - (unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address + (unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address else return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address } @@ -281,10 +291,11 @@ int printframe( char *buf, int len, int i, void *addr ) struct sigaction oldFilter; -#define STACK_BACKTRACE_STR_LEN 17 -#define STACK_BACKTRACE_STR "Stack backtrace:\n" -#define STACK_DUMP_STR_LEN 12 -#define STACK_DUMP_STR "Stack dump:\n" +#define STACK_BACKTRACE_STR "Stack backtrace:\n" +#define STACK_DUMP_STR "Stack dump:\n" + +#define STACK_BACKTRACE_STR_LEN (sizeof( STACK_BACKTRACE_STR ) - 1) +#define STACK_DUMP_STR_LEN (sizeof( STACK_DUMP_STR ) - 1) #define ALIGN( x, y ) (((uintptr_t) (x) + ((y)-1)) & ~((y)-1)) static void Sys_Crash( int signal, siginfo_t *si, void *context) @@ -356,7 +367,7 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context) len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr ); #endif - write( 2, message, len ); + write( STDERR_FILENO, message, len ); // flush buffers before writing directly to descriptors fflush( stdout ); @@ -370,9 +381,9 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context) { size_t pagesize = sysconf( _SC_PAGESIZE ); // try to print backtrace - write( 2, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN ); + write( STDERR_FILENO, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN ); write( logfd, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN ); - strncpy( message + len, STACK_BACKTRACE_STR, sizeof( message ) - len ); + Q_strncpy( message + len, STACK_BACKTRACE_STR, sizeof( message ) - len ); len += STACK_BACKTRACE_STR_LEN; // false on success, true on failure @@ -384,8 +395,8 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context) do { - int line = printframe( message + len, sizeof( message ) - len, ++i, pc); - write( 2, message + len, line ); + int line = Sys_PrintFrame( message + len, sizeof( message ) - len, ++i, pc); + write( STDERR_FILENO, message + len, line ); write( logfd, message + len, line ); len += line; //if( !dladdr(bp,0) ) break; // only when bp is in module @@ -399,17 +410,17 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context) while( bp && i < 128 ); // try to print stack - write( 2, STACK_DUMP_STR, STACK_DUMP_STR_LEN ); + write( STDERR_FILENO, STACK_DUMP_STR, STACK_DUMP_STR_LEN ); write( logfd, STACK_DUMP_STR, STACK_DUMP_STR_LEN ); - strncpy( message + len, STACK_DUMP_STR, sizeof( message ) - len ); + Q_strncpy( message + len, STACK_DUMP_STR, sizeof( message ) - len ); len += STACK_DUMP_STR_LEN; if( !try_allow_read( sp, pagesize ) ) { for( i = 0; i < 32; i++ ) { - int line = printframe( message + len, sizeof( message ) - len, i, sp[i] ); - write( 2, message + len, line ); + int line = Sys_PrintFrame( message + len, sizeof( message ) - len, i, sp[i] ); + write( STDERR_FILENO, message + len, line ); write( logfd, message + len, line ); len += line; }