You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden ========================== MAJOR FEATURES + CHANGES ========================== Change 2845644 on 2016/01/27 by Martin.Wilson Clear marker sync flag after creating tick record, add more information to checks incase issue occurs again #Jira OR-13469 #rb Thomas.Sarkanen #tests in editor tests, bot match. Change 2845613 on 2016/01/27 by John.Pollard Latest network profiler binaries #rb none #tests run profiler Change 2845595 on 2016/01/27 by Mieszko.Zielinski Fixed pathfollowing's block detection using wrong distance when testing for blockage #UE4 #rb Lukasz.Furman #test golden path Change 2845593 on 2016/01/27 by Jeff.Farris Added support for setting and choosing filmbacks and lenses for cinematic cameras. - New CineCameraComponent and CineCameraActor classes - can define filmback and lens presets via ini file - details customizations for filmback and lens selection - added prototype set of filmbacks and lenses (primes and zooms) - Camera details customization now gracefully handles when CameraSettings category is hidden - example sequencer usage is content/developers/jeff.farris/CineCams/CineCamTestMap #rb none #tests editor Change 2845585 on 2016/01/27 by Marcus.Wassmer Don't fool with connected state if we're early outing from the OS intercepting controller events. This fixes some missing delegates. Fixes cert bug about controller disconnect screen staying up permanently #rb Cody.Haskell #test Turning off controller, turning on again. #lockdown Andrew.Grant Change 2845528 on 2016/01/27 by Max.Chen Sequencer: Fix new spawnables not immediately getting an object binding. This was resulted in a missing +Track->Animation when first creating a spawnable and duplicate transform keys. #jira UE-26084 #tests Add spawnable, +Track->Animation exists #rb none Change 2845483 on 2016/01/27 by Andrew.Rodham Sequencer: Fixed MaximizedViewport not getting cleared/restored correctly #jria UE-26016 #rb Max.Chen #tests Tested the viewports Change 2845421 on 2016/01/27 by Max.Preussner Sequencer: Implemented go-to feature #RB max.chen #TESTS Editor Change 2845407 on 2016/01/27 by Max.Preussner Sequencer: Moved SetViewRange() into ISequencer and made it public #RB max.chen #TESTS none Change 2845404 on 2016/01/27 by Andrew.Rodham Sequencer: Fixed cinematic viewport not updating when dragging transport range #jira UE-26003 #rb Max.Chen #tests Scrubbed the timeline Change 2845396 on 2016/01/27 by David.Nikdel #OSS #Purchase #Store #PS4 - Minor log cleanup #RB: none #TESTS: compiles Change 2845375 on 2016/01/27 by Max.Chen Sequencer: Implement cinematic shot track thumbnails. #jira UE-25125 #tests Rebuild the trailer with the cinematic shot track #rb none Change 2845359 on 2016/01/27 by Marcus.Wassmer Downgrade some checks to ensures. #rb none #test ps4 Change 2845347 on 2016/01/27 by Nicholas.Davies Remove unused EditorStyle dependency from Social. It is not being used, and causes issues for the engine team. #RB Antony.Carter #TESTS n/a #codereview Robert.Manuszewski Change 2845227 on 2016/01/27 by Robert.Manuszewski Adding flags to create callstack map files when building Arxan protection #rb none #tests Built arxan exe Change 2844871 on 2016/01/26 by Andrew.Grant Prevent enums from being regenerated while cooking (prevents false-positive warning about FText's being regenerated) #rb none #tests ran editor [CL 2847722 by Andrew Grant in Main branch]
417 lines
14 KiB
C++
417 lines
14 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "CrashReportClientApp.h"
|
|
#include "GenericPlatformCrashContext.h"
|
|
|
|
#include "XmlFile.h"
|
|
#include "CrashDescription.h"
|
|
#include "CrashReportAnalytics.h"
|
|
#include "CrashReportUtil.h"
|
|
#include "Runtime/Analytics/Analytics/Public/Analytics.h"
|
|
#include "Runtime/Analytics/Analytics/Public/Interfaces/IAnalyticsProvider.h"
|
|
#include "EngineBuildSettings.h"
|
|
|
|
// #CrashReport: 2015-07-23 Move crashes from C:\Users\[USER]\AppData\Local\Microsoft\Windows\WER\ReportQueue to C:\Users\[USER]\AppData\Local\CrashReportClient\Saved
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FCrashProperty
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FCrashProperty::FCrashProperty( const FString& InMainCategory, const FString& InSecondCategory, FPrimaryCrashProperties* InOwner )
|
|
: Owner( InOwner )
|
|
, CachedValue( TEXT("") )
|
|
, MainCategory( InMainCategory )
|
|
, SecondCategory( InSecondCategory )
|
|
, bSet( false )
|
|
{
|
|
|
|
}
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const FString& NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = NewValue;
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const TCHAR* NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = NewValue;
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const TArray<FString>& NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = Owner->EncodeArrayStringAsXMLString( NewValue );
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const bool NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = NewValue ? TEXT( "1" ) : TEXT( "0" );
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
FCrashProperty& FCrashProperty::operator=(const int64 NewValue)
|
|
{
|
|
bSet = true;
|
|
CachedValue = LexicalConversion::ToString( NewValue );
|
|
Owner->SetCrashProperty( MainCategory, SecondCategory, CachedValue );
|
|
return *this;
|
|
}
|
|
|
|
const FString& FCrashProperty::AsString() const
|
|
{
|
|
if (!bSet)
|
|
{
|
|
Owner->GetCrashProperty( CachedValue, MainCategory, SecondCategory );
|
|
bSet = true;
|
|
}
|
|
return CachedValue;
|
|
}
|
|
|
|
|
|
bool FCrashProperty::AsBool() const
|
|
{
|
|
return AsString().ToBool();
|
|
}
|
|
|
|
int64 FCrashProperty::AsInt64() const
|
|
{
|
|
int64 Value = 0;
|
|
TTypeFromString<int64>::FromString( Value, *AsString() );
|
|
return Value;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FPrimaryCrashProperties
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FPrimaryCrashProperties* FPrimaryCrashProperties::Singleton = nullptr;
|
|
|
|
FPrimaryCrashProperties::FPrimaryCrashProperties()
|
|
// At this moment only these properties can be changed by the crash report client.
|
|
: PlatformFullName( FGenericCrashContext::RuntimePropertiesTag, TEXT( "PlatformFullName" ), this )
|
|
, CommandLine( FGenericCrashContext::RuntimePropertiesTag, TEXT( "CommandLine" ), this )
|
|
, UserName( FGenericCrashContext::RuntimePropertiesTag, TEXT("UserName"), this )
|
|
, MachineId( FGenericCrashContext::RuntimePropertiesTag, TEXT( "MachineId" ), this )
|
|
, EpicAccountId( FGenericCrashContext::RuntimePropertiesTag, TEXT( "EpicAccountId" ), this )
|
|
// Multiline properties
|
|
, CallStack( FGenericCrashContext::RuntimePropertiesTag, TEXT( "CallStack" ), this )
|
|
, SourceContext( FGenericCrashContext::RuntimePropertiesTag, TEXT( "SourceContext" ), this )
|
|
, Modules( FGenericCrashContext::RuntimePropertiesTag, TEXT( "Modules" ), this )
|
|
, UserDescription( FGenericCrashContext::RuntimePropertiesTag, TEXT( "UserDescription" ), this )
|
|
, UserActivityHint( FGenericCrashContext::RuntimePropertiesTag, TEXT( "UserActivityHint" ), this )
|
|
, ErrorMessage( FGenericCrashContext::RuntimePropertiesTag, TEXT( "ErrorMessage" ), this )
|
|
, FullCrashDumpLocation( FGenericCrashContext::RuntimePropertiesTag, TEXT( "FullCrashDumpLocation" ), this )
|
|
, TimeOfCrash( FGenericCrashContext::RuntimePropertiesTag, TEXT( "TimeOfCrash" ), this )
|
|
, bAllowToBeContacted( FGenericCrashContext::RuntimePropertiesTag, TEXT( "bAllowToBeContacted" ), this )
|
|
, XmlFile( nullptr )
|
|
{
|
|
CrashVersion = ECrashDescVersions::VER_1_NewCrashFormat;
|
|
CrashDumpMode = ECrashDumpMode::Default;
|
|
bHasMiniDumpFile = false;
|
|
bHasLogFile = false;
|
|
bHasPrimaryData = false;
|
|
}
|
|
|
|
void FPrimaryCrashProperties::Shutdown()
|
|
{
|
|
delete Get();
|
|
}
|
|
|
|
void FPrimaryCrashProperties::UpdateIDs()
|
|
{
|
|
const bool bAddPersonalData = FCrashReportClientConfig::Get().GetAllowToBeContacted() || FEngineBuildSettings::IsInternalBuild();
|
|
bAllowToBeContacted = bAddPersonalData;
|
|
if (bAddPersonalData)
|
|
{
|
|
// The Epic ID can be looked up from this ID.
|
|
EpicAccountId = FPlatformMisc::GetEpicAccountId();
|
|
}
|
|
else
|
|
{
|
|
EpicAccountId = FString();
|
|
}
|
|
|
|
// Add real user name only if log files were allowed since the user name is in the log file and the user consented to sending this information.
|
|
const bool bSendUserName = FCrashReportClientConfig::Get().GetSendLogFile() || FEngineBuildSettings::IsInternalBuild();
|
|
if (bSendUserName)
|
|
{
|
|
// Remove periods from user names to match AutoReporter user names
|
|
// The name prefix is read by CrashRepository.AddNewCrash in the website code
|
|
UserName = FString( FPlatformProcess::UserName() ).Replace( TEXT( "." ), TEXT( "" ) );
|
|
}
|
|
else
|
|
{
|
|
UserName = FString();
|
|
}
|
|
|
|
MachineId = FPlatformMisc::GetMachineId().ToString( EGuidFormats::Digits );
|
|
}
|
|
|
|
void FPrimaryCrashProperties::ReadXML( const FString& CrashContextFilepath )
|
|
{
|
|
XmlFilepath = CrashContextFilepath;
|
|
XmlFile = new FXmlFile( XmlFilepath );
|
|
TimeOfCrash = FDateTime::UtcNow().GetTicks();
|
|
UpdateIDs();
|
|
}
|
|
|
|
void FPrimaryCrashProperties::SetCrashGUID( const FString& Filepath )
|
|
{
|
|
FString CrashDirectory = FPaths::GetPath( Filepath );
|
|
FPaths::NormalizeDirectoryName( CrashDirectory );
|
|
// Grab the last component...
|
|
CrashGUID = FPaths::GetCleanFilename( CrashDirectory );
|
|
}
|
|
|
|
FString FPrimaryCrashProperties::EncodeArrayStringAsXMLString( const TArray<FString>& ArrayString ) const
|
|
{
|
|
const FString Encoded = FString::Join( ArrayString, TEXT("\n") );
|
|
return Encoded;
|
|
}
|
|
|
|
void FPrimaryCrashProperties::SendAnalytics()
|
|
{
|
|
// Connect the crash report client analytics provider.
|
|
FCrashReportAnalytics::Initialize();
|
|
|
|
IAnalyticsProvider& Analytics = FCrashReportAnalytics::GetProvider();
|
|
|
|
TArray<FAnalyticsEventAttribute> CrashAttributes;
|
|
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "bHasPrimaryData" ), bHasPrimaryData ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "CrashVersion" ), (int32)CrashVersion ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "CrashGUID" ), CrashGUID ) );
|
|
|
|
// AppID = GameName
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "GameName" ), GameName ) );
|
|
|
|
// AppVersion = EngineVersion
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EngineVersion" ), EngineVersion.ToString() ) );
|
|
|
|
// @see UpdateIDs()
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "MachineID" ), MachineId.AsString() ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "UserName" ), UserName.AsString() ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EpicAccountId" ), EpicAccountId.AsString() ) );
|
|
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "Platform" ), PlatformFullName.AsString() ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "TimeOfCrash" ), TimeOfCrash.AsString() ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EngineMode" ), EngineMode ) );
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "AppDefaultLocale" ), AppDefaultLocale ) );
|
|
|
|
CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "UserActivityHint" ), UserActivityHint.AsString() ) );
|
|
|
|
Analytics.RecordEvent( TEXT( "CrashReportClient.ReportCrash" ), CrashAttributes );
|
|
|
|
// Shutdown analytics.
|
|
FCrashReportAnalytics::Shutdown();
|
|
}
|
|
|
|
void FPrimaryCrashProperties::Save()
|
|
{
|
|
XmlFile->Save( XmlFilepath );
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FCrashContextReader
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FCrashContext::FCrashContext( const FString& CrashContextFilepath )
|
|
{
|
|
ReadXML( CrashContextFilepath );
|
|
|
|
const bool bIsValid = XmlFile->IsValid();
|
|
if (bIsValid)
|
|
{
|
|
// Setup properties required for the analytics.
|
|
GetCrashProperty( CrashVersion, FGenericCrashContext::RuntimePropertiesTag, TEXT( "CrashVersion" ) );
|
|
GetCrashProperty( CrashGUID, FGenericCrashContext::RuntimePropertiesTag, TEXT( "CrashGUID" ) );
|
|
GetCrashProperty( CrashDumpMode, FGenericCrashContext::RuntimePropertiesTag, TEXT( "CrashDumpMode" ) );
|
|
GetCrashProperty( GameName, FGenericCrashContext::RuntimePropertiesTag, TEXT( "GameName" ) );
|
|
GetCrashProperty( EngineVersion, FGenericCrashContext::RuntimePropertiesTag, TEXT( "EngineVersion" ) );
|
|
|
|
GetCrashProperty( BaseDir, FGenericCrashContext::RuntimePropertiesTag, TEXT( "BaseDir" ) );
|
|
FString Misc_OSVersionMajor;
|
|
GetCrashProperty( Misc_OSVersionMajor, FGenericCrashContext::RuntimePropertiesTag, TEXT( "Misc.OSVersionMajor" ) );
|
|
FString Misc_OSVersionMinor;
|
|
GetCrashProperty( Misc_OSVersionMinor, FGenericCrashContext::RuntimePropertiesTag, TEXT( "Misc.OSVersionMinor" ) );
|
|
|
|
bool Misc_Is64bitOperatingSystem = false;
|
|
GetCrashProperty( Misc_Is64bitOperatingSystem, FGenericCrashContext::RuntimePropertiesTag, TEXT( "Misc.Is64bitOperatingSystem" ) );
|
|
|
|
// Extract the Platform component.
|
|
TArray<FString> SubDirs;
|
|
BaseDir.ParseIntoArray( SubDirs, TEXT( "/" ), true );
|
|
const int SubDirsNum = SubDirs.Num();
|
|
const FString PlatformName = SubDirsNum > 0 ? SubDirs[SubDirsNum - 1] : TEXT( "" );
|
|
if (Misc_OSVersionMajor.Len() > 0)
|
|
{
|
|
PlatformFullName = FString::Printf( TEXT( "%s [%s %s %s]" ), *PlatformName, *Misc_OSVersionMajor, *Misc_OSVersionMinor, Misc_Is64bitOperatingSystem ? TEXT( "64b" ) : TEXT( "32b" ) );
|
|
}
|
|
else
|
|
{
|
|
PlatformFullName = PlatformName;
|
|
}
|
|
|
|
GetCrashProperty( EngineMode, FGenericCrashContext::RuntimePropertiesTag, TEXT( "EngineMode" ) );
|
|
GetCrashProperty( AppDefaultLocale, FGenericCrashContext::RuntimePropertiesTag, TEXT( "AppDefaultLocale" ) );
|
|
|
|
if (CrashDumpMode == ECrashDumpMode::FullDump)
|
|
{
|
|
// Set the full dump crash location when we have a full dump.
|
|
const FString LocationForBranch = FCrashReportClientConfig::Get().GetFullCrashDumpLocationForBranch( EngineVersion.GetBranch() );
|
|
if (!LocationForBranch.IsEmpty())
|
|
{
|
|
FullCrashDumpLocation = LocationForBranch / CrashGUID + TEXT("_") + EngineVersion.ToString();
|
|
}
|
|
}
|
|
|
|
bHasPrimaryData = true;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FCrashDescription
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FCrashWERContext::FCrashWERContext( const FString& WERXMLFilepath )
|
|
: FPrimaryCrashProperties()
|
|
{
|
|
ReadXML( WERXMLFilepath );
|
|
CrashGUID = FPaths::GetCleanFilename( FPaths::GetPath( WERXMLFilepath ) );
|
|
|
|
const bool bIsValid = XmlFile->IsValid();
|
|
if (bIsValid)
|
|
{
|
|
FString BuildVersion;
|
|
FString BranchName;
|
|
uint32 BuiltFromCL = 0;
|
|
int EngineVersionComponents = 0;
|
|
|
|
GetCrashProperty( GameName, TEXT( "ProblemSignatures" ), TEXT( "Parameter0" ) );
|
|
|
|
GetCrashProperty( BuildVersion, TEXT( "ProblemSignatures" ), TEXT( "Parameter1" ) );
|
|
if (!BuildVersion.IsEmpty())
|
|
{
|
|
EngineVersionComponents++;
|
|
}
|
|
|
|
FString Parameter8Value;
|
|
GetCrashProperty( Parameter8Value, TEXT( "ProblemSignatures" ), TEXT( "Parameter8" ) );
|
|
if (!Parameter8Value.IsEmpty())
|
|
{
|
|
TArray<FString> ParsedParameters8;
|
|
Parameter8Value.ParseIntoArray( ParsedParameters8, TEXT( "!" ), false );
|
|
|
|
if (ParsedParameters8.Num() > 1)
|
|
{
|
|
CommandLine = FGenericCrashContext::UnescapeXMLString( ParsedParameters8[1] );
|
|
CrashDumpMode = CommandLine.AsString().Contains( TEXT( "-fullcrashdump" ) ) ? ECrashDumpMode::FullDump : ECrashDumpMode::Default;
|
|
}
|
|
|
|
if (ParsedParameters8.Num() > 2)
|
|
{
|
|
ErrorMessage = ParsedParameters8[2];
|
|
}
|
|
}
|
|
|
|
FString Parameter9Value;
|
|
GetCrashProperty( Parameter9Value, TEXT( "ProblemSignatures" ), TEXT( "Parameter9" ) );
|
|
if (!Parameter9Value.IsEmpty())
|
|
{
|
|
TArray<FString> ParsedParameters9;
|
|
Parameter9Value.ParseIntoArray( ParsedParameters9, TEXT( "!" ), false );
|
|
|
|
if (ParsedParameters9.Num() > 0)
|
|
{
|
|
BranchName = ParsedParameters9[0].Replace( TEXT( "+" ), TEXT( "/" ) );
|
|
|
|
const FString DepotRoot = TEXT( "//depot/" );
|
|
if (BranchName.StartsWith( DepotRoot ))
|
|
{
|
|
BranchName = BranchName.Mid( DepotRoot.Len() );
|
|
}
|
|
EngineVersionComponents++;
|
|
}
|
|
|
|
if (ParsedParameters9.Num() > 1)
|
|
{
|
|
const FString BaseDirectory = ParsedParameters9[1];
|
|
|
|
TArray<FString> SubDirs;
|
|
BaseDirectory.ParseIntoArray( SubDirs, TEXT( "/" ), true );
|
|
const int SubDirsNum = SubDirs.Num();
|
|
const FString PlatformName = SubDirsNum > 0 ? SubDirs[SubDirsNum - 1] : TEXT( "" );
|
|
|
|
FString Product;
|
|
GetCrashProperty( Product, TEXT( "OSVersionInformation" ), TEXT( "Product" ) );
|
|
if (Product.Len() > 0)
|
|
{
|
|
PlatformFullName = FString::Printf( TEXT( "%s [%s]" ), *PlatformName, *Product );
|
|
}
|
|
else
|
|
{
|
|
PlatformFullName = PlatformName;
|
|
}
|
|
}
|
|
|
|
if (ParsedParameters9.Num() > 2)
|
|
{
|
|
EngineMode = ParsedParameters9[2];
|
|
}
|
|
|
|
if (ParsedParameters9.Num() > 3)
|
|
{
|
|
TTypeFromString<uint32>::FromString( BuiltFromCL, *ParsedParameters9[3] );
|
|
EngineVersionComponents++;
|
|
}
|
|
}
|
|
|
|
// We have all three components of the engine version, so initialize it.
|
|
if (EngineVersionComponents == 3)
|
|
{
|
|
InitializeEngineVersion( BuildVersion, BranchName, BuiltFromCL );
|
|
}
|
|
|
|
bHasPrimaryData = true;
|
|
}
|
|
}
|
|
|
|
void FCrashWERContext::InitializeEngineVersion( const FString& BuildVersion, const FString& BranchName, uint32 BuiltFromCL )
|
|
{
|
|
uint16 Major = 0;
|
|
uint16 Minor = 0;
|
|
uint16 Patch = 0;
|
|
|
|
TArray<FString> ParsedBuildVersion;
|
|
BuildVersion.ParseIntoArray( ParsedBuildVersion, TEXT( "." ), false );
|
|
|
|
if (ParsedBuildVersion.Num() >= 3)
|
|
{
|
|
TTypeFromString<uint16>::FromString( Patch, *ParsedBuildVersion[2] );
|
|
}
|
|
|
|
if (ParsedBuildVersion.Num() >= 2)
|
|
{
|
|
TTypeFromString<uint16>::FromString( Minor, *ParsedBuildVersion[1] );
|
|
}
|
|
|
|
if (ParsedBuildVersion.Num() >= 1)
|
|
{
|
|
TTypeFromString<uint16>::FromString( Major, *ParsedBuildVersion[0] );
|
|
}
|
|
|
|
EngineVersion = FEngineVersion( Major, Minor, Patch, BuiltFromCL, BranchName );
|
|
}
|