Description
Overview
Out of the box unreal provides its own crash reporting tools to handle incidents on supported platforms. After initial investigation its been deemed work a deeper investigation and experimental implementation.
Locations of Interest
Unreal has aspects of the crash reporter distributed across multiple areas of the engine but there are a few key locations of note.
Crash Report Client :https://github.com/EpicGames/UnrealEngine/tree/release/Engine/Source/Programs/CrashReportClient
Root for core level abstractions.(This includes the stackwalker, crash context and more) :https://github.com/EpicGames/UnrealEngine/tree/release/Engine/Source/Runtime/Core/Public/GenericPlatform
Crash Report Core:https://github.com/EpicGames/UnrealEngine/tree/release/Engine/Source/Runtime/CrashReportCore
Gpu Crash:
UnrealEngine/Engine/Source/Runtime/RenderCore/Private/GPUDebugCrashUtils.cpp at release · EpicGames/UnrealEngine
UnrealEngine/Engine/Source/Runtime/RenderCore/Private/DumpGPU.cpp at release · EpicGames/UnrealEngine
Information Tracked
Variable | Comment |
---|---|
CrashGUID | An unique report name that this crash belongs to. Folder name |
GameName | The name of the game that crashed. (AppID) |
ExecutableName | The name of the exe that crashed. (AppID) |
EngineMode | The mode the game was in e.g. editor. |
DeploymentName | Deployment (also known as "EpicApp"), e.g. DevPlaytest, PublicTest, Live |
EngineModeEx | EngineModeEx e.g. Unset, Dirty, Vanilla |
PlatformFullName | The platform that crashed e.g. Win64. |
EngineVersion | Encoded engine version. (AppVersion) E.g. 4.3.0.0-2215663+UE-Releases+4.3 BuildVersion-BuiltFromCL-BranchName |
CommandLine | The command line of the application that crashed. |
BaseDir | The base directory where the app was running. |
AppDefaultLocale | The language ID the application that crashed. |
UserName | The name of the user that caused this crash. |
LoginId | The unique ID used to identify the machine the crash occurred on. |
EpicAccountId | The Epic account ID for the user who last used the Launcher. |
GameSessionID | The last game session id set by the application. Application specific meaning. Some might not set this. |
PCallStackHash | A hash representing a unique id for a portable callstack. These will be specific to the CL version of the application |
CrashSignal | The signal that was raised to enter the crash handler |
NumMinidumpFramesToIgnore | Specifies the number of stack frames in the callstack to ignore when symbolicating from a minidump. |
CallStack | An array of FStrings representing the callstack of the crash. |
SourceContext | An array of FStrings showing the source code around the crash. |
Modules | An array of module's name used by the game that crashed. |
UserDescription | An array of FStrings representing the user description of the crash. |
UserActivityHint | An FString representing the user activity, if known, when the error occurred. |
ErrorMessage | The error message, can be assertion message, ensure message or message from the fatal error. |
FullCrashDumpLocation | Location of full crash dump. Displayed in the crash report frontend. |
TimeOfCrash | The UTC time the crash occurred. |
bAllowToBeContacted | Whether the user allowed us to be contacted. f true the following properties are retrieved from the system: UserName (for non-launcher build) and EpicAccountID. |
CrashReporterMessage | Rich text string (should be localized by the crashing application) that will be displayed in the main CRC dialog Can be empty and the CRC's default text will be shown. |
PlatformCallbackResult | Platform-specific UE Core value (integer). |
CrashReportClientVersion | CRC sets this to the current version of the software. |
bHasMiniDumpFile | Whether this crash has a minidump file. |
bHasLogFile | Whether this crash has a log file. |
bHasPrimaryData | Whether this crash contains primary usable data. |
RestartCommandLine | Copy of CommandLine that isn't anonymized so it can be used to restart the process |
bIsEnsure | Whether the report comes from a non-fatal event such as an ensure |
CrashType | The type of crash being reported, e.g. Assert, Ensure, Hang |
CPUBrand | The cpu brand of the device, e.g. Intel, iPhone6, etc. |
Threads | Thread contexts, XML elements containing info specific to an active thread, e.g. callstacks |
PlatformPropertiesExtras | Optional additional data for platform properties |
bIsOOM | Whether it was an OOM (Out Of Memory) or not |
bLowMemoryWarning | Whether we got a low memory warning or not |
bInBackground | Whether we were in the background when the crash happened |
bIsRequestingExit | Whether we crashed during shutdown |
Implementation Challenges
After reaching out to get more information on how native handles backends it came to my attention that we will run into issues supporting this crash handler. This is because the selected backend must exist at compile time with the current setup. This wouldn't be possible for unreal with the current setup as you would have to make unreal a 3rd party to native.
Reasons to Support Unreal Crash
There are a handful of reasons we may want to move forward with the Unreal Crash Handler. The biggest reason is we gain access to GPU related crash data such as Hangs and Device loss errors. In game development this is a very important aspect of error coverage. This is something that was recently request GPU crashes not captured by Sentry plugin · Issue #673
In terms of the wider dump information it doesn't look like there is to much information here that we don't already track but there is the potential for more detailed engine information that we do not normally tack such as the execution command line and the crash report message from the engine potentially pointing to the problem.
With Unreal's crash handler I believe it supports all target platforms at least in some form (currently not able to validate closed platforms). This could potentially expedite any porting projects and ensuring compatibility with all engine exports.
Additionally we also gain much better legacy support for the engine as the crash handler very rarely receives API breaking changes. This would mean that we can support much older engine versions with at worse just some minor version defines.
Finally this would solve ongoing issues with the current crash handler has been known to break compatibility via its updates. Currently this has required significant resources to fix these recurring update issues that could better be applied elsewhere.
What do we lose
One thing to note is we would likely have to do everything in-process this is a mix of a few limitations, first of all i believe we are limited on the marketplace side where we are not able to distribute executables programs. Additionally I believe that plugins are not capable of building executables therefore we would have to run a engine fork instead of a plugin similar to how NVidia operate there forks.
From what i can see the current Crashpad solution captures more raw system and crash information not directly related to Unreal itself. This level of information could potentially still be useful for developers.
Solutions
Option A
One potential option if we intend to move forward is open up native to allow for runtime backends. By doing this we would be able to add Unreal Crash Core as a backend into native with minimal changes to the current unreal plugin. I also believe this could be a benefit to native allowing other developers to inject there custom crash handlers as required.
Option B
Another potential solution is compiling a custom sentry native as part of the plugin, this version would have Unreal as a dependency and implement the crash handler in question. Currently this is my least desired approach as it would likely cause maintenance issues ensuring that this native version says in step with the main version. It would also introduce build complexity adding a custom 3rd party to compile as part of the build process.
Option 3
An option that was suggested whilst gathering info on native is potentially dropping native completely a re-implementing its behavior via unreal. This means we would re-implement much of the higher level API on sentry whilst using unreals packet and messaging system to send the data to Sentry. This provides a few gains on paper such as a simplified build system as we no longer need to pull native from CI but also comes with some tradeoffs like scale of work required to implement and maintain this new API.
Metadata
Metadata
Assignees
Type
Projects
Status