@ -24,9 +24,11 @@ Crash handler, called from system
@@ -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 <winnt.h>
# include <dbghelp.h>
# include <psapi.h>
@ -35,7 +37,7 @@ Crash handler, called from system
@@ -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 )
@@ -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 ; i < moduleCount ; i + + )
for ( i = 0 ; i < moduleCount ; i + + )
{
MODULEINFO info ;
GetModuleInformation ( process , moduleArray [ i ] , & info , sizeof ( MODULEINFO ) ) ;
@ -73,9 +72,10 @@ int ModuleName( HANDLE process, char *name, void *address, int len )
@@ -73,9 +72,10 @@ int ModuleName( HANDLE process, char *name, void *address, int len )
( ( DWORD64 ) address < ( DWORD64 ) info . lpBaseOfDll + ( DWORD64 ) info . SizeOfImage ) )
return GetModuleBaseName ( process , moduleArray [ i ] , name , len ) ;
}
return Q_snprintf ( name , len , " ??? " ) ;
return Q_snprintf ( name , len , " ??? " ) ;
}
static void stack_trace ( PEXCEPTION_POINTERS pInfo )
static void Sys_StackTrace ( PEXCEPTION_POINTERS pInfo )
{
char message [ 1024 ] ;
int len = 0 ;
@ -89,7 +89,8 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
@@ -89,7 +89,8 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
STACKFRAME64 stackframe ;
DWORD image ;
memcpy ( & context , pInfo - > ContextRecord , 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 )
@@ -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 )
@@ -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 )
@@ -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 )
@@ -190,7 +199,7 @@ long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
host . crashed = true ;
# if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
stack_t race( pInfo ) ;
Sys_StackT race( 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 )
@@ -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 <ucontext.h>
# endif
# include <signal.h>
# include <sys/mman.h>
@ -261,7 +271,7 @@ static int d_dladdr( void *sym, Dl_info *info )
@@ -261,7 +271,7 @@ static int d_dladdr( void *sym, Dl_info *info )
# define dladdr d_dladdr
# endif
int printf rame( char * buf , int len , int i , void * addr )
static int Sys_PrintF rame( 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 )
@@ -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 )
@@ -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)
@@ -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)
@@ -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)
@@ -384,8 +395,8 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
do
{
int line = printf rame( message + len , sizeof ( message ) - len , + + i , pc ) ;
write ( 2 , message + len , line ) ;
int line = Sys_PrintF rame( 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)
@@ -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 = printf rame( message + len , sizeof ( message ) - len , i , sp [ i ] ) ;
write ( 2 , message + len , line ) ;
int line = Sys_PrintF rame( message + len , sizeof ( message ) - len , i , sp [ i ] ) ;
write ( STDERR_FILENO , message + len , line ) ;
write ( logfd , message + len , line ) ;
len + = line ;
}