@ -7,12 +7,28 @@
# include "windows_crashmonitor.hpp"
# include "windows_crashmonitor.hpp"
# include "windows_crashshm.hpp"
# include "windows_crashshm.hpp"
# include "windowscrashdumppathhelpers.hpp"
# include <SDL_messagebox.h>
# include <SDL_messagebox.h>
# include <components/misc/strings/conversion.hpp>
# include <components/misc/strings/conversion.hpp>
namespace Crash
namespace Crash
{
{
namespace
{
template < class T , std : : size_t N >
void writePathToShm ( T ( & buffer ) [ N ] , const std : : filesystem : : path & path )
{
memset ( buffer , 0 , sizeof ( buffer ) ) ;
const auto str = path . u8string ( ) ;
size_t length = str . length ( ) ;
if ( length > = sizeof ( buffer ) )
length = sizeof ( buffer ) - 1 ;
strncpy_s ( buffer , sizeof ( buffer ) ,
Misc : : StringUtils : : u8StringToString ( str ) . c_str ( ) , length ) ;
buffer [ length ] = ' \0 ' ;
}
}
HANDLE duplicateHandle ( HANDLE handle )
HANDLE duplicateHandle ( HANDLE handle )
{
{
@ -27,8 +43,8 @@ namespace Crash
CrashCatcher * CrashCatcher : : sInstance = nullptr ;
CrashCatcher * CrashCatcher : : sInstance = nullptr ;
CrashCatcher : : CrashCatcher (
CrashCatcher : : CrashCatcher ( int argc , char * * argv , const std : : filesystem : : path & dumpPath ,
int argc , char * * argv , const std : : filesystem : : path & crashDump Path , const std : : filesystem : : path & freezeDump Path )
const std : : filesystem : : path & crashDump Name , const std : : filesystem : : path & freezeDump Name )
{
{
assert ( sInstance = = nullptr ) ; // don't allow two instances
assert ( sInstance = = nullptr ) ; // don't allow two instances
@ -50,7 +66,7 @@ namespace Crash
if ( ! shmHandle )
if ( ! shmHandle )
{
{
setupIpc ( ) ;
setupIpc ( ) ;
startMonitorProcess ( crashDumpPath, freezeDumpPath ) ;
startMonitorProcess ( dumpPath, crashDumpName , freezeDumpName ) ;
installHandler ( ) ;
installHandler ( ) ;
}
}
else
else
@ -77,28 +93,22 @@ namespace Crash
CloseHandle ( mShmHandle ) ;
CloseHandle ( mShmHandle ) ;
}
}
void CrashCatcher : : updateDumpPaths (
void CrashCatcher : : updateDumpPath ( const std : : filesystem : : path & dumpPath )
const std : : filesystem : : path & crashDumpPath , const std : : filesystem : : path & freezeDumpPath )
{
{
shmLock ( ) ;
shmLock ( ) ;
memset ( mShm - > mStartup . mCrashDumpFilePath , 0 , sizeof ( mShm - > mStartup . mCrashDumpFilePath ) ) ;
writePathToShm ( mShm - > mStartup . mDumpDirectoryPath , dumpPath ) ;
const auto str = crashDumpPath . u8string ( ) ;
size_t length = str . length ( ) ;
shmUnlock ( ) ;
if ( length > = MAX_LONG_PATH )
}
length = MAX_LONG_PATH - 1 ;
strncpy_s ( mShm - > mStartup . mCrashDumpFilePath , sizeof mShm - > mStartup . mCrashDumpFilePath ,
void CrashCatcher : : updateDumpNames (
Misc : : StringUtils : : u8StringToString ( str ) . c_str ( ) , length ) ;
const std : : filesystem : : path & crashDumpName , const std : : filesystem : : path & freezeDumpName )
mShm - > mStartup . mCrashDumpFilePath [ length ] = ' \0 ' ;
{
shmLock ( ) ;
memset ( mShm - > mStartup . mFreezeDumpFilePath , 0 , sizeof ( mShm - > mStartup . mFreezeDumpFilePath ) ) ;
writePathToShm ( mShm - > mStartup . mCrashDumpFileName , crashDumpName ) ;
const auto strFreeze = freezeDumpPath . u8string ( ) ;
writePathToShm ( mShm - > mStartup . mFreezeDumpFileName , freezeDumpName ) ;
length = strFreeze . length ( ) ;
if ( length > = MAX_LONG_PATH )
length = MAX_LONG_PATH - 1 ;
strncpy_s ( mShm - > mStartup . mFreezeDumpFilePath , sizeof mShm - > mStartup . mFreezeDumpFilePath ,
Misc : : StringUtils : : u8StringToString ( strFreeze ) . c_str ( ) , length ) ;
mShm - > mStartup . mFreezeDumpFilePath [ length ] = ' \0 ' ;
shmUnlock ( ) ;
shmUnlock ( ) ;
}
}
@ -153,8 +163,8 @@ namespace Crash
SetUnhandledExceptionFilter ( vectoredExceptionHandler ) ;
SetUnhandledExceptionFilter ( vectoredExceptionHandler ) ;
}
}
void CrashCatcher : : startMonitorProcess (
void CrashCatcher : : startMonitorProcess ( const std : : filesystem : : path & dumpPath ,
const std : : filesystem : : path & crashDump Path , const std : : filesystem : : path & freezeDump Path )
const std : : filesystem : : path & crashDump Name , const std : : filesystem : : path & freezeDump Name )
{
{
std : : wstring executablePath ;
std : : wstring executablePath ;
DWORD copied = 0 ;
DWORD copied = 0 ;
@ -165,23 +175,9 @@ namespace Crash
} while ( copied > = executablePath . size ( ) ) ;
} while ( copied > = executablePath . size ( ) ) ;
executablePath . resize ( copied ) ;
executablePath . resize ( copied ) ;
memset ( mShm - > mStartup . mCrashDumpFilePath , 0 , sizeof ( mShm - > mStartup . mCrashDumpFilePath ) ) ;
writePathToShm ( mShm - > mStartup . mDumpDirectoryPath , dumpPath ) ;
const auto str = crashDumpPath . u8string ( ) ;
writePathToShm ( mShm - > mStartup . mCrashDumpFileName , crashDumpName ) ;
size_t length = str . length ( ) ;
writePathToShm ( mShm - > mStartup . mFreezeDumpFileName , freezeDumpName ) ;
if ( length > = MAX_LONG_PATH )
length = MAX_LONG_PATH - 1 ;
strncpy_s ( mShm - > mStartup . mCrashDumpFilePath , sizeof mShm - > mStartup . mCrashDumpFilePath ,
Misc : : StringUtils : : u8StringToString ( str ) . c_str ( ) , length ) ;
mShm - > mStartup . mCrashDumpFilePath [ length ] = ' \0 ' ;
memset ( mShm - > mStartup . mFreezeDumpFilePath , 0 , sizeof ( mShm - > mStartup . mFreezeDumpFilePath ) ) ;
const auto strFreeze = freezeDumpPath . u8string ( ) ;
length = strFreeze . length ( ) ;
if ( length > = MAX_LONG_PATH )
length = MAX_LONG_PATH - 1 ;
strncpy_s ( mShm - > mStartup . mFreezeDumpFilePath , sizeof mShm - > mStartup . mFreezeDumpFilePath ,
Misc : : StringUtils : : u8StringToString ( strFreeze ) . c_str ( ) , length ) ;
mShm - > mStartup . mFreezeDumpFilePath [ length ] = ' \0 ' ;
// note that we don't need to lock the SHM here, the other process has not started yet
// note that we don't need to lock the SHM here, the other process has not started yet
mShm - > mEvent = CrashSHM : : Event : : Startup ;
mShm - > mEvent = CrashSHM : : Event : : Startup ;
@ -204,6 +200,9 @@ namespace Crash
if ( ! CreateProcessW ( executablePath . data ( ) , arguments . data ( ) , NULL , NULL , TRUE , 0 , NULL , NULL , & si , & pi ) )
if ( ! CreateProcessW ( executablePath . data ( ) , arguments . data ( ) , NULL , NULL , TRUE , 0 , NULL , NULL , & si , & pi ) )
throw std : : runtime_error ( " Could not start crash monitor process " ) ;
throw std : : runtime_error ( " Could not start crash monitor process " ) ;
CloseHandle ( pi . hProcess ) ;
CloseHandle ( pi . hThread ) ;
waitMonitor ( ) ;
waitMonitor ( ) ;
}
}
@ -241,7 +240,7 @@ namespace Crash
waitMonitor ( ) ;
waitMonitor ( ) ;
std : : string message = " OpenMW has encountered a fatal error. \n Crash log saved to ' "
std : : string message = " OpenMW has encountered a fatal error. \n Crash log saved to ' "
+ std: : string ( mShm - > mStartup . mCrashDumpFilePath )
+ Misc: : StringUtils : : u8StringToString ( getCrashDumpPath ( * mShm ) . u8string ( ) )
+ " '. \n Please report this to https://gitlab.com/OpenMW/openmw/issues ! " ;
+ " '. \n Please report this to https://gitlab.com/OpenMW/openmw/issues ! " ;
SDL_ShowSimpleMessageBox ( 0 , " Fatal Error " , message . c_str ( ) , nullptr ) ;
SDL_ShowSimpleMessageBox ( 0 , " Fatal Error " , message . c_str ( ) , nullptr ) ;
}
}