You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2877442 on 2016/02/23 by Graeme.Thornton@GThornton_DevCore
Allow 'dumpnonframe' stat command to also take an optional group name which will filter the output
Change 2879289 on 2016/02/24 by Graeme.Thornton@GThornton_DevCore
Removed "-" in switch string for load time tracker. Makes -NoLoadTrackClear cmd line param actually work
Change 2879323 on 2016/02/24 by Graeme.Thornton@GThornton_DevCore
PC builds now log engine initialization time with the load time tracker
Change 2879418 on 2016/02/24 by Graeme.Thornton@GThornton_DevCore
Optimization for FSignedArchiveReader
- Compute incoming data hash in parallel on another thread while we serialize and decrypt the signature on the chunk cache worker thread
Change 2879419 on 2016/02/24 by Graeme.Thornton@GThornton_DevCore
Extra stats for PakFile group
- Time reading from pak handles
- Number of open pak handles
Change 2881199 on 2016/02/25 by Graeme.Thornton@GThornton_DevCore
Use 32 bit CRCs to hash chunk contents rather than SHA1. Much faster to compute than SHA1, and the decrypting 4 bytes rather than 20 is also a lot faster
Change 2885687 on 2016/02/29 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Close disregard for GC pool when disabling it to leave it in a good state.
Change 2887358 on 2016/03/01 by Steve.Robb@Dev-Core
FlushCurrentThreadCache calls forwarded on from FMalloc wrappers.
Change 2887398 on 2016/03/01 by Steve.Robb@Dev-Core
Stats for MallocBinned2.
Change 2887682 on 2016/03/01 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added code to catch game hangs. If game thread is stalled for more than 5 seconds we will catch that, report its callstack and crash.
Change 2889573 on 2016/03/02 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Renamed the new StackWalkAndDump to ThreadStackWalkAndDump to avoid name collisions and build errors.
Change 2889687 on 2016/03/02 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Send thread heartbeats during potentially slow tasks.
Change 2889963 on 2016/03/02 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added the ability to query the name of a thread given its TLS id.
Change 2890439 on 2016/03/02 by Steve.Robb@Dev-Core
MallocBinned redirection header, to allow easy switching between MallocBinned and MallocBinned2.
Switch back to MallocBinned by default.
Change 2891799 on 2016/03/03 by Steve.Robb@Dev-Core
Shrunken GMallocBinned2MemSizeToIndex array.
Improvement of some shared templated alignment-related functions.
Change 2891812 on 2016/03/03 by Graeme.Thornton@GThornton_DevCore
Refactoring of pak signing to be more compatible with patching
- Store signatures in a block at the end of the pak file
- Optimize decryption of signatures by serializing them all when the pak is opened, and decrypting on the chunk cache worker thread between read requests.
Change 2891813 on 2016/03/03 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Don't compile UnrealPak with ICU
Change 2892386 on 2016/03/03 by Steve.Robb@Dev-Core
GitHub #2070 - Fix incorrect FMallocDebug::Malloc alignment checking
Change 2894189 on 2016/03/04 by Steve.Robb@Dev-Core
Memswap fixes for sizes of 3, 5, 6 and 7, and early out on 0.
Change 2894427 on 2016/03/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Don't display message boxes in unattended mode when D3D device is removed.
Change 2896912 on 2016/03/07 by Graeme.Thornton@GThornton_DevCore
Disable reading of anything outside the pak file when in shipping builds
Change 2897053 on 2016/03/07 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
A few improvements to thread heartbeat thread:
- Don't check for heartbeat in debug builds
- Don't spawn the thread heartbeat thread for programs
- Ignore stalls when exiting
Change 2898752 on 2016/03/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fixing race conditions when using malloc verify
Change 2899075 on 2016/03/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
UnrealPak will now accept hex values for p and q. Added the command line param to trust p and q.
Change 2899091 on 2016/03/08 by Steve.Robb@Dev-Core
Fix for TQueue::Peek const-correctness.
Change 2902775 on 2016/03/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Adding code to test signature keys.
Change 2905040 on 2016/03/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
TBigInt Multiply is now 30x faster
Change 2905218 on 2016/03/11 by Steve.Robb@Dev-Core
New FCString::Strspn and FCString::Strcspn functions.
[CL 2921423 by Robert Manuszewski in Main branch]
631 lines
18 KiB
C#
631 lines
18 KiB
C#
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Xml.Serialization;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Tools.DotNETCommon.XmlHandler;
|
|
using System.Xml;
|
|
using System.Linq;
|
|
using System.Security;
|
|
using System.Diagnostics;
|
|
|
|
namespace Tools.CrashReporter.CrashReportCommon
|
|
{
|
|
/*
|
|
Unused Crashes' fields.
|
|
|
|
Title nchar(20)
|
|
Selected bit
|
|
Version int
|
|
AutoReporterID int
|
|
Processed bit
|
|
HasDiagnosticsFile bit
|
|
HasNewLogFile bit
|
|
HasMetaData bit
|
|
|
|
Fields of Crashes used only by the crash report website.
|
|
|
|
Status varchar(64) - Status of the crash.
|
|
Pattern varchar(800) - Pattern used to group cashes into buggs.
|
|
FixedChangeList varchar(64) - Changelist that fixed this crash.
|
|
Module varchar(128) - Name of the module where the crash occurred.
|
|
UserNameId int - The ID of the user name.
|
|
Jira varchar(64) - The Jira.
|
|
CrashType smallint NOT NULL - The type of the crash, crash(1), assert(2), ensure(3)
|
|
*/
|
|
|
|
/* PrimaryCrashProperties. Extracted from: FGenericCrashContext::SerializeContentToBuffer */
|
|
/*
|
|
"CrashVersion"
|
|
"ProcessId"
|
|
"CrashGUID"
|
|
"IsInternalBuild"
|
|
"IsPerforceBuild"
|
|
"IsSourceDistribution"
|
|
"SecondsSinceStart"
|
|
"GameName"
|
|
"ExecutableName"
|
|
"BuildConfiguration"
|
|
"PlatformName"
|
|
"PlatformNameIni"
|
|
"PlatformFullName"
|
|
"EngineMode"
|
|
"EngineVersion"
|
|
"CommandLine"
|
|
"LanguageLCID"
|
|
"AppDefaultLocale"
|
|
"IsUE4Release"
|
|
"UserName"
|
|
"BaseDir"
|
|
"RootDir"
|
|
"MachineId"
|
|
"EpicAccountId"
|
|
"CallStack"
|
|
"SourceContext"
|
|
"UserDescription"
|
|
"UserActivityHint"
|
|
"ErrorMessage"
|
|
"CrashDumpMode"
|
|
"Misc.NumberOfCores"
|
|
"Misc.NumberOfCoresIncludingHyperthreads"
|
|
"Misc.Is64bitOperatingSystem"
|
|
"Misc.CPUVendor"
|
|
"Misc.CPUBrand"
|
|
"Misc.PrimaryGPUBrand"
|
|
"Misc.OSVersionMajor"
|
|
"Misc.OSVersionMinor"
|
|
"Misc.AppDiskTotalNumberOfBytes"
|
|
"Misc.AppDiskNumberOfFreeBytes"
|
|
"MemoryStats.TotalPhysical"
|
|
"MemoryStats.TotalVirtual"
|
|
"MemoryStats.PageSize"
|
|
"MemoryStats.TotalPhysicalGB"
|
|
"MemoryStats.AvailablePhysical"
|
|
"MemoryStats.AvailableVirtual"
|
|
"MemoryStats.UsedPhysical"
|
|
"MemoryStats.PeakUsedPhysical"
|
|
"MemoryStats.UsedVirtual"
|
|
"MemoryStats.PeakUsedVirtual"
|
|
"MemoryStats.bIsOOM"
|
|
"MemoryStats.OOMAllocationSize"
|
|
"MemoryStats.OOMAllocationAlignment"
|
|
"TimeofCrash"
|
|
"bAllowToBeContacted"
|
|
*/
|
|
|
|
/// <summary> Enumerates crash description versions. </summary>
|
|
public enum ECrashDescVersions
|
|
{
|
|
/// <summary> Introduces a new crash description format. </summary>
|
|
VER_1_NewCrashFormat,
|
|
|
|
/// <summary> Added misc properties (CPU,GPU,OS,etc), memory related stats and platform specific properties as generic payload. </summary>
|
|
VER_2_AddedNewProperties,
|
|
|
|
/// <summary> Using crash context when available. </summary>
|
|
VER_3_CrashContext = 3,
|
|
}
|
|
|
|
/// <summary>
|
|
/// GenericCrashContext for managed code. Based on XML file.
|
|
/// Holds data from the CrashContext.runtime-xml file
|
|
/// Must match FGenericCrashContext::SerializeContentToBuffer
|
|
///
|
|
/// 1. Generated by FGenericCrashContext::SerializeContentToBuffer via the native code
|
|
/// 2. Updated with callstack, source context etc via the crash report client / crash report process
|
|
/// 3. Read by the crash report process, verified and forward in the same form to the crash report frontend
|
|
/// 4. Basic properties displayed directly in the frontend (already existing in the database), remaining properties are displayed per crash read from the CrashContext.runtime-xml file.
|
|
///
|
|
/// <RuntimeCrashDescription></RuntimeCrashDescription>
|
|
/// <version></version>
|
|
/// <PlatformSpecificProperties>
|
|
///
|
|
/// </PlatformSpecificProperties>
|
|
/// </summary>
|
|
public class FGenericCrashContext
|
|
{
|
|
/// <summary> Name of the crash context file. </summary>
|
|
public const string CrashContextRuntimeXMLName = "CrashContext.runtime-xml";
|
|
|
|
/// <summary>Required properties</summary>
|
|
[XmlElement( ElementName = "RuntimeProperties" )]
|
|
public FPrimaryCrashProperties PrimaryCrashProperties = new FPrimaryCrashProperties();
|
|
|
|
/// <summary>Optional, platform specific properties</summary>
|
|
[XmlElement( ElementName = "PlatformProperties" )]
|
|
public object UntypedXMLNodes;
|
|
|
|
/// <summary> Directory of the crash. </summary>
|
|
public string CrashDirectory;
|
|
|
|
//// <summary> Platform specific properties. </summary>
|
|
//[XmlElement]
|
|
//public List<KeyValuePair<string, string>> PlatformProperties = new List<KeyValuePair<string, string>>();
|
|
|
|
/// <summary>A simple default constructor to allow Xml serialization.</summary>
|
|
public FGenericCrashContext()
|
|
{
|
|
}
|
|
|
|
/// <summary> Creates a new instance of the crash report context from the specified file. </summary>
|
|
public static FGenericCrashContext FromFile( string Filepath )
|
|
{
|
|
// The crash report context contains invalid characters, we need to fix them all in order to parse the XML.
|
|
HashSet<string> TagsToIgnore = new HashSet<string>() { "<FGenericCrashContext>", "<RuntimeProperties>", "<PlatformProperties>", "</FGenericCrashContext>", "</RuntimeProperties>", "</PlatformProperties>" };
|
|
|
|
string[] XMLText = File.ReadAllLines( Filepath );
|
|
string CopyText = string.Join( Environment.NewLine, XMLText );
|
|
|
|
string NodeOpen = "";
|
|
string NodeEnd = "";
|
|
|
|
List<string> Multiline = new List<string>();
|
|
List<int> MultiIndex = new List<int>();
|
|
|
|
int OpenEnd = 0;
|
|
int EndStart = 0;
|
|
for (int LineIndex = 1; LineIndex < XMLText.Length; LineIndex++)
|
|
{
|
|
string XMLLine = XMLText[LineIndex].Replace( "\t", "" );
|
|
bool bIgnore = TagsToIgnore.Contains( XMLLine );
|
|
if (bIgnore)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// XML node without data, skip.
|
|
if (XMLLine.Contains( "/>" ))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (NodeOpen == "")
|
|
{
|
|
// Parse the tag.
|
|
//<Version>"1"</Version>
|
|
//<Version />
|
|
int OpenStart = XMLLine.IndexOf( '<' );
|
|
OpenEnd = XMLLine.IndexOf( '>', OpenStart );
|
|
NodeOpen = XMLLine.Substring( OpenStart + 1, OpenEnd - OpenStart - 1 );
|
|
}
|
|
|
|
EndStart = XMLLine.IndexOf( "</" );
|
|
int EndEnd = 0;
|
|
if (EndStart != -1)
|
|
{
|
|
EndEnd = XMLLine.IndexOf( '>', EndStart );
|
|
NodeEnd = XMLLine.Substring( EndStart + 2, EndEnd - EndStart - 2 );
|
|
}
|
|
else
|
|
{
|
|
Multiline.Add( XMLLine.Substring( OpenEnd != 0 ? OpenEnd + 1 : 0 ) );
|
|
MultiIndex.Add( LineIndex );
|
|
OpenEnd = 0;
|
|
}
|
|
|
|
// Valid tag, fix invalid characters.
|
|
if (NodeOpen == NodeEnd)
|
|
{
|
|
if (Multiline.Count == 0)
|
|
{
|
|
string NodeValue = XMLLine.Substring( OpenEnd + 1, EndStart - OpenEnd - 1 );
|
|
string EscapedXMLText = EscapeXMLString( UnescapeXMLString( NodeValue ) ); // Required for support old and new type format.
|
|
XMLText[LineIndex] = string.Format( "<{0}>{1}</{0}>", NodeOpen, EscapedXMLText );
|
|
}
|
|
else
|
|
{
|
|
Multiline.Add( XMLLine.Substring( 0, EndStart ) );
|
|
MultiIndex.Add( LineIndex );
|
|
|
|
for (int Inner = 0; Inner < Multiline.Count; Inner++)
|
|
{
|
|
string EscapedXMLText = EscapeXMLString( UnescapeXMLString( Multiline[Inner] ) );
|
|
|
|
if (Inner == 0)
|
|
{
|
|
XMLText[MultiIndex[Inner]] = string.Format( "<{0}>{1}", NodeOpen, EscapedXMLText );
|
|
}
|
|
else if (Inner == Multiline.Count - 1)
|
|
{
|
|
XMLText[MultiIndex[Inner]] = string.Format( "{1}</{0}>", NodeOpen, EscapedXMLText );
|
|
}
|
|
else
|
|
{
|
|
XMLText[MultiIndex[Inner]] = EscapedXMLText;
|
|
}
|
|
}
|
|
|
|
Multiline.Clear();
|
|
MultiIndex.Clear();
|
|
}
|
|
|
|
NodeOpen = NodeEnd = "";
|
|
}
|
|
}
|
|
|
|
string XMLTextJoined = string.Join( Environment.NewLine, XMLText );
|
|
FGenericCrashContext Context = XmlHandler.FromXmlString<FGenericCrashContext>( XMLTextJoined );
|
|
|
|
if (Context.UntypedXMLNodes != null)
|
|
{
|
|
var Typed = ( (IEnumerable)Context.UntypedXMLNodes )
|
|
.Cast<XmlNode>()
|
|
.Select( X => new KeyValuePair<string, string>( X.Name, X.InnerText ) )
|
|
.ToList();
|
|
}
|
|
|
|
return Context;
|
|
}
|
|
|
|
const string NewLineTag = "&nl;";
|
|
|
|
/// <summary> Escape XML string. </summary>
|
|
static public string EscapeXMLString( string Text )
|
|
{
|
|
return Text
|
|
.Replace( "&", "&" )
|
|
.Replace( "\"", """ )
|
|
.Replace( "'", "'" )
|
|
.Replace( "<", "<" )
|
|
.Replace( ">", ">" )
|
|
// Ignore return carriage.
|
|
.Replace( "\r", "" );
|
|
//.Replace( "\n", NewLineTag );
|
|
}
|
|
|
|
/// <summary> Unescape XML string. </summary>
|
|
static public string UnescapeXMLString( string Text )
|
|
{
|
|
return Text
|
|
.Replace( "&", "&" )
|
|
.Replace( """, "\"" )
|
|
.Replace( "'", "'" )
|
|
.Replace( "<", "<" )
|
|
.Replace( ">", ">" )
|
|
.Replace( NewLineTag, "\n" );
|
|
}
|
|
|
|
/// <summary> Whether this crash contains callstack, error message and source context thus it means that crash is complete. </summary>
|
|
public bool HasProcessedData()
|
|
{
|
|
return !string.IsNullOrEmpty(PrimaryCrashProperties.CallStack) &&
|
|
!string.IsNullOrEmpty(PrimaryCrashProperties.ErrorMessage);
|
|
}
|
|
|
|
/// <summary> Writes this instance of the crash report context to the specified file. </summary>
|
|
public void ToFile()
|
|
{
|
|
XmlHandler.WriteXml<FGenericCrashContext>( this, Path.Combine( CrashDirectory, FGenericCrashContext.CrashContextRuntimeXMLName ) );
|
|
}
|
|
|
|
/// <returns>Unique name of this report, can be used as name of file.</returns>
|
|
public string GetAsFilename()
|
|
{
|
|
string EngineVersion = PrimaryCrashProperties.EngineVersion;
|
|
|
|
string Directory = string.Format( "{0}_{1}__{2}", EngineVersion, !string.IsNullOrEmpty( PrimaryCrashProperties.GameName ) ? PrimaryCrashProperties.GameName : "NO_GAMENAME", PrimaryCrashProperties.TimeofCrash.Ticks );
|
|
return Directory;
|
|
}
|
|
}
|
|
|
|
/*
|
|
"EngineVersion"
|
|
*/
|
|
|
|
/// <summary> Required properties for the generic crash context. </summary>
|
|
public class FPrimaryCrashProperties
|
|
{
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public int CrashVersion;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string CrashGUID;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public int ProcessId;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public bool IsInternalBuild;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public bool IsPerforceBuild;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public bool IsSourceDistribution;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public int SecondsSinceStart;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string GameName;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string ExecutableName;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string BuildConfiguration;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string PlatformName;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string PlatformNameIni;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string PlatformFullName;
|
|
|
|
/// <summary>
|
|
/// Creates a full platform name, if missing. PlatformName [OS.Major Os.Minor Arch]
|
|
/// Must match
|
|
/// ...\Engine\Source\Programs\CrashReporter\CrashReportClient\Private\CrashDescription.cpp FCrashContext.FCrashContext
|
|
///</summary>
|
|
public void SetPlatformFullName()
|
|
{
|
|
if (string.IsNullOrEmpty( PlatformFullName ))
|
|
{
|
|
// Create a new one.
|
|
string LocalPlatformName = "";
|
|
if (BaseDir != "")
|
|
{
|
|
string[] FolderComponents = BaseDir.Split( new[] { '/' }, StringSplitOptions.RemoveEmptyEntries );
|
|
if (FolderComponents.Length != 0)
|
|
{
|
|
LocalPlatformName = FolderComponents[FolderComponents.Length - 1];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LocalPlatformName = PlatformNameIni;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty( Misc_OSVersionMajor ))
|
|
{
|
|
PlatformFullName = string.Format( "{0} [{1} {2} {3}]",
|
|
LocalPlatformName,
|
|
Misc_OSVersionMajor,
|
|
string.IsNullOrEmpty( Misc_OSVersionMinor ) ? "" : Misc_OSVersionMinor,
|
|
Misc_Is64bitOperatingSystem ? "64b" : "32b" );
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string EngineMode;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string EngineVersion;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string CommandLine;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public int LanguageLCID;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string AppDefaultLocale;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public bool IsUE4Release;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string UserName;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string BaseDir;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string RootDir;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string MachineId;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string EpicAccountId;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string CallStack;
|
|
|
|
/// <summary> Callstack as string[] unescaped. </summary>
|
|
public string[] GetCallstack()
|
|
{
|
|
string UnescapedValue = FGenericCrashContext.UnescapeXMLString( CallStack );
|
|
return UnescapedValue.Split( new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries );
|
|
}
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string UserActivityHint;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string SourceContext;
|
|
|
|
/// <summary> SourceContext as string[] unescaped. </summary>
|
|
public string[] GetSourceContext()
|
|
{
|
|
string UnescapedValue = FGenericCrashContext.UnescapeXMLString( SourceContext );
|
|
return UnescapedValue.Split( new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries );
|
|
}
|
|
|
|
/// <summary> An array of module's name used by the game that crashed. </summary>
|
|
[XmlElement]
|
|
public string Modules;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string UserDescription;
|
|
|
|
/// <summary> UserDescription as string[] unescaped. </summary>
|
|
public string[] GetUserDescription()
|
|
{
|
|
string UnescapedValue = FGenericCrashContext.UnescapeXMLString( UserDescription );
|
|
return UnescapedValue.Split( new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries );
|
|
}
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public string ErrorMessage;
|
|
|
|
/// <summary> ErrorMessage as string[] unescaped. </summary>
|
|
public string[] GetErrorMessage()
|
|
{
|
|
string UnescapedValue = FGenericCrashContext.UnescapeXMLString( ErrorMessage );
|
|
UnescapedValue = UnescapedValue.Substring( 0, Math.Min( 511, UnescapedValue.Length ) ); // Database limitation.
|
|
return UnescapedValue.Split( new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries );
|
|
}
|
|
|
|
/// <summary> Location of the full crash dump. Displayed in the crash report frontend, without the filename. </summary>
|
|
[XmlElement]
|
|
public string FullCrashDumpLocation;
|
|
|
|
/// <summary> Fullname of the full crash dump.</summary>
|
|
public string GetFullCrashDumpLocation()
|
|
{
|
|
string Fullname = Path.Combine( FullCrashDumpLocation, CrashReporterConstants.UE4MinidumpName );
|
|
return Fullname;
|
|
}
|
|
|
|
/// <summary></summary>
|
|
[XmlElement]
|
|
public int CrashDumpMode;
|
|
|
|
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.NumberOfCores" )]
|
|
public int Misc_NumberOfCores;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.NumberOfCoresIncludingHyperthreads" )]
|
|
public int Misc_NumberOfCoresIncludingHyperthreads;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.Is64bitOperatingSystem" )]
|
|
public bool Misc_Is64bitOperatingSystem;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.CPUVendor" )]
|
|
public string Misc_CPUVendor;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.CPUBrand" )]
|
|
public string Misc_CPUBrand;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.PrimaryGPUBrand" )]
|
|
public string Misc_PrimaryGPUBrand;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.OSVersionMajor" )]
|
|
public string Misc_OSVersionMajor;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.OSVersionMinor" )]
|
|
public string Misc_OSVersionMinor;
|
|
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.AppDiskTotalNumberOfBytes")]
|
|
public string Misc_AppDiskTotalNumberOfBytes;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "Misc.AppDiskNumberOfFreeBytes")]
|
|
public string Misc_AppDiskNumberOfFreeBytes;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.TotalPhysical")]
|
|
public string MemoryStats_TotalPhysical;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.TotalVirtual")]
|
|
public string MemoryStats_TotalVirtual;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.PageSize")]
|
|
public string MemoryStats_PageSize;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.TotalPhysicalGB")]
|
|
public string MemoryStats_TotalPhysicalGB;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.AvailablePhysical")]
|
|
public string MemoryStats_AvailablePhysical;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.AvailableVirtual")]
|
|
public string MemoryStats_AvailableVirtual;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.UsedPhysical")]
|
|
public string MemoryStats_UsedPhysical;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.PeakUsedPhysical")]
|
|
public string MemoryStats_PeakUsedPhysical;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.UsedVirtual")]
|
|
public string MemoryStats_UsedVirtual;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.PeakUsedVirtual")]
|
|
public string MemoryStats_PeakUsedVirtual;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.bIsOOM")]
|
|
public string MemoryStats_bIsOOM;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.OOMAllocationSize")]
|
|
public string MemoryStats_OOMAllocationSize;
|
|
|
|
/// <summary></summary>
|
|
[XmlElement( ElementName = "MemoryStats.OOMAllocationAlignment")]
|
|
public string MemoryStats_OOMAllocationAlignment;
|
|
|
|
|
|
/// <summary>The UTC time the crash occurred.</summary>
|
|
[XmlElement]
|
|
public DateTime TimeofCrash;
|
|
|
|
/// <summary> Whether the user allowed us to be contacted. </summary>
|
|
[XmlElement]
|
|
public bool bAllowToBeContacted = false;
|
|
|
|
/// <summary> Warning info for missing data or failed processing in the Crash Report Processor. </summary>
|
|
[XmlElement]
|
|
public string ProcessorFailedMessage;
|
|
|
|
/// <summary>A simple default constructor to allow Xml serialization.</summary>
|
|
public FPrimaryCrashProperties()
|
|
{ }
|
|
}
|
|
} |