bool FCrashDebugHelperWindows::CreateMinidumpDiagnosticReport( const FString& InCrashDumpFilename ) { bool bResult = false; const bool bSyncSymbols = FParse::Param( FCommandLine::Get(), TEXT( "SyncSymbols" ) ); const bool bAnnotate = FParse::Param( FCommandLine::Get(), TEXT( "Annotate" ) ); const bool bSyncMicrosoftSymbols = FParse::Param( FCommandLine::Get(), TEXT( "SyncMicrosoftSymbols" ) ); const bool bUseSCC = bSyncSymbols || bAnnotate || bSyncMicrosoftSymbols; if( bUseSCC ) { InitSourceControl(false); } FWindowsPlatformStackWalkExt::InitStackWalking(); if( FWindowsPlatformStackWalkExt::OpenDumpFile( &CrashInfo, InCrashDumpFilename ) ) { // Get a list of modules, and the version of the executable FWindowsPlatformStackWalkExt::GetModuleList( &CrashInfo ); // If a BuiltFromCL was specified, use that instead of the one parsed from the executable if (BuiltFromCL > 0) { CrashInfo.ChangelistBuiltFrom = BuiltFromCL; } if( CrashInfo.ChangelistBuiltFrom != -1 ) { // CrashInfo now contains a changelist to lookup a label for if( bSyncSymbols ) { CrashInfo.LabelName = RetrieveBuildLabel( -1, CrashInfo.ChangelistBuiltFrom ); if( CrashInfo.LabelName.Len() > 0 ) { // Sync all the modules, and their associated pdbs CrashInfo.Log( FString::Printf( TEXT( " ... found label '%s'; syncing all modules to this label" ), *CrashInfo.LabelName ) ); SyncModules( &CrashInfo ); } } // Initialise the symbol options FWindowsPlatformStackWalkExt::InitSymbols( &CrashInfo ); // Set the symbol path based on the loaded modules FWindowsPlatformStackWalkExt::SetSymbolPathsFromModules( &CrashInfo ); // Get all the info we should ever need about the modules FWindowsPlatformStackWalkExt::GetModuleInfoDetailed( &CrashInfo ); // Get info about the system that created the minidump FWindowsPlatformStackWalkExt::GetSystemInfo( &CrashInfo ); // Get all the thread info FWindowsPlatformStackWalkExt::GetThreadInfo( &CrashInfo ); // Get exception info FWindowsPlatformStackWalkExt::GetExceptionInfo( &CrashInfo ); // Get the callstacks for each thread FWindowsPlatformStackWalkExt::GetCallstacks( &CrashInfo ); // Sync the source file where the crash occurred if( CrashInfo.SourceFile.Len() > 0 ) { if( bSyncSymbols ) { CrashInfo.Log( FString::Printf( TEXT( " ... using label '%s' to sync crash source file" ), *CrashInfo.LabelName ) ); SyncSourceFile( &CrashInfo ); } // Try to annotate the file if requested bool bAnnotationSuccessful = false; if( bAnnotate ) { bAnnotationSuccessful = AddAnnotatedSourceToReport( &CrashInfo ); } // If annotation is not requested, or failed, add the standard source context if( !bAnnotationSuccessful ) { AddSourceToReport( &CrashInfo ); } } } else { CrashInfo.Log( FString::Printf( TEXT( "CreateMinidumpDiagnosticReport: Failed to find executable image; possibly pathless module names?" ), *InCrashDumpFilename ) ); } } else { CrashInfo.Log( FString::Printf( TEXT( "CreateMinidumpDiagnosticReport: Failed to open crash dump file: %s" ), *InCrashDumpFilename ) ); } FWindowsPlatformStackWalkExt::ShutdownStackWalking(); if( bUseSCC ) { ShutdownSourceControl(); } return bResult; }
bool FCrashDebugHelperWindows::CreateMinidumpDiagnosticReport( const FString& InCrashDumpFilename ) { const bool bSyncSymbols = FParse::Param( FCommandLine::Get(), TEXT( "SyncSymbols" ) ); const bool bAnnotate = FParse::Param( FCommandLine::Get(), TEXT( "Annotate" ) ); const bool bUseSCC = bSyncSymbols || bAnnotate; if( bUseSCC ) { InitSourceControl( false ); } FWindowsPlatformStackWalkExt WindowsStackWalkExt( CrashInfo ); const bool bReady = WindowsStackWalkExt.InitStackWalking(); bool bHasAtLeastThreeValidFunctions = false; if( bReady && WindowsStackWalkExt.OpenDumpFile( InCrashDumpFilename ) ) { if( CrashInfo.BuiltFromCL != FCrashInfo::INVALID_CHANGELIST ) { // CrashInfo now contains a changelist to lookup a label for if( bSyncSymbols ) { // Get the build version from the crash info. FCrashModuleInfo ExeFileVersion; WindowsStackWalkExt.GetExeFileVersionAndModuleList( ExeFileVersion ); FindSymbolsAndBinariesStorage(); const bool bSynced = SyncModules(); // Without symbols we can't decode the provided minidump. if( !bSynced ) { return 0; } } // Initialise the symbol options WindowsStackWalkExt.InitSymbols(); // Set the symbol path based on the loaded modules WindowsStackWalkExt.SetSymbolPathsFromModules(); // Get all the info we should ever need about the modules WindowsStackWalkExt.GetModuleInfoDetailed(); // Get info about the system that created the minidump WindowsStackWalkExt.GetSystemInfo(); // Get all the thread info WindowsStackWalkExt.GetThreadInfo(); // Get exception info WindowsStackWalkExt.GetExceptionInfo(); // Get the callstacks for each thread bHasAtLeastThreeValidFunctions = WindowsStackWalkExt.GetCallstacks() >= 3; // Sync the source file where the crash occurred if( CrashInfo.SourceFile.Len() > 0 ) { if( bSyncSymbols && CrashInfo.BuiltFromCL > 0 ) { UE_LOG( LogCrashDebugHelper, Log, TEXT( "Using CL %i to sync crash source file" ), CrashInfo.BuiltFromCL ); SyncSourceFile(); } // Try to annotate the file if requested bool bAnnotationSuccessful = false; if( bAnnotate ) { bAnnotationSuccessful = AddAnnotatedSourceToReport(); } // If annotation is not requested, or failed, add the standard source context if( !bAnnotationSuccessful ) { AddSourceToReport(); } } } else { UE_LOG( LogCrashDebugHelper, Warning, TEXT( "Invalid built from changelist" ) ); } } else { UE_LOG( LogCrashDebugHelper, Warning, TEXT( "Failed to open crash dump file: %s" ), *InCrashDumpFilename ); } if( bUseSCC ) { ShutdownSourceControl(); } return bHasAtLeastThreeValidFunctions; }