Setting Up Backtrace for Unreal Engine
Add Backtrace to your Unreal Engine project to automatically detect and report native crashes that occur in your game.
Backtrace supports Unreal Engine's Crash Reporter, therefore installation of a Backtrace SDK is not required to capture crashes.
Features
The Backtrace Unreal plugin reports on the following types of errors:
- Crashes - An end to the game play experience, where the game crashes or restarts.
- Hangs (mobile only) - Errors that occur when a game or an app is non-responsive.
- Out of memory crashes (mobile only) - Terminations of your game or app due to low memory conditions.
- Asserts - Used to detect and diagnose unexpected or invalid runtime conditions during development.
Supported Platforms
Supported Platforms | Supported Systems |
---|---|
Mobile | Android, iOS |
PC | Windows, MacOS, Linux |
Game Consoles | PlayStation 4, PlayStation 5, Xbox One, Xbox Series X, Xbox Series S, Nintendo Switch, Steam Deck |
For on-premise (self-hosted) users, the integration for Unreal Engine requires specific packages. For more information, contact support.
What You'll Need
- A Backtrace account (log in or sign up for a free trial license).
- Your subdomain name (used to connect to your Backtrace instance). For example,
https://example-subdomain.sp.backtrace.io
. - A Backtrace project and a submission token.
System Requirements
- Unreal Engine version 4.16 to 5.2
Initialize the Backtrace Client
- Windows
- Android
- iOS
- macOS
- Linux
- Game Consoles
- Steam Deck
For Crashes in the Editor
-
In the root directory for your Unreal Engine project, open the Config folder.
-
Copy the
DefaultEngine.ini
file and paste it into the Engine > Config folder.noteIf the Engine folder doesn't exist at the root directory for your Unreal Engine project, create a new folder and name it Engine. Then in the Engine folder, create another folder and name it Config.
-
Rename the file to
UserEngine.ini
. -
Open the
UserEngine.ini
file and add the following lines:[CrashReportClient]
CrashReportClientVersion=1.0
DataRouterUrl="https://unreal.backtrace.io/post/{subdomain}/{submission-token}" -
For the
DataRouterUrl
, provide the name of your subdomain and a submission token.
For Crashes in Packaged Builds
Enable the Crash Reporter
- In the Unreal Editor, go to Edit > Project Settings.
- In the Project Settings, search for "crash reporter".
- Under Packaging, enable Include Crash Reporter.
If you're building from the command line, add the -crashreporter
flag.
Configure the Crash Reporter
You can configure the crash reporter to be the default for all packaged builds or for a single packaged build.To configure the crash reporter as the default for all packaged builds:- In the root directory for your Unreal Engine project, open the Config folder.
- Copy the
DefaultEngine.ini
file and paste it into the following directory:[UNREAL_ENGINE]/UnrealEngine/Engine/Programs/CrashReportClient/Config
noteThe directory could also be under
C:/Program Files/Epic Games/UE_[version]
. You can also search your system for 'CrashReportClient' to find it. - Open the
DefaultEngine.ini
file and add the following lines:[CrashReportClient]
CrashReportClientVersion=1.0
DataRouterUrl="https://unreal.backtrace.io/post/{subdomain}/{submission-token}" - For the
DataRouterUrl
, provide the name of your subdomain and a submission token.
- In the root directory for your Unreal Engine project, open the Config folder.
- Copy the
DefaultEngine.ini
file and paste it into the following directory:- For Unreal Engine 4.25 and earlier:
[BUILD_DIRECTORY]/WindowsNoEditor/Engine/Programs/CrashReportClient/Config/NoRedist
- For Unreal Engine 4.26 and higher:
[BUILD_DIRECTORY]/WindowsNoEditor/Engine/Restricted/NoRedist/Programs/CrashReportClient/Config
noteCreate the subdirectories if they do not exist.
- For Unreal Engine 4.25 and earlier:
- Open the
DefaultEngine.ini
file and add the following lines:[CrashReportClient]
CrashReportClientVersion=1.0
DataRouterUrl="https://unreal.backtrace.io/post/{subdomain}/{submission-token}" - For the
DataRouterUrl
, provide the name of your subdomain and a submission token.
-
Download BacktraceAndroid_UPL.xml.
-
In the
BacktraceAndroid_UPL.xml
file, provide the name of your subdomain and a submission token forBacktraceCredentials
.- Java:
BacktraceCredentials credentials = new BacktraceCredentials("https://submit.backtrace.io/{subdomain}/{submission-token}/json");
- Kotlin:
val backtraceCredentials = BacktraceCredentials("https://submit.backtrace.io/{subdomain}/{submission-token}/json")
- Java:
-
In the directory for your Unreal Engine project, locate your app or game's
Build.cs
file. -
Place the
BacktraceAndroid_UPL.xml
file in the same directory with theBuild.cs
file. -
In the
Build.cs
file, add the following lines at the end of theModuleRules
class constructor:if (Target.Platform == UnrealTargetPlatform.Android)
{
string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
AdditionalPropertiesForReceipt.Add("AndroidPlugin", System.IO.Path.Combine(PluginPath, "BacktraceAndroid_UPL.xml"));
} -
Download the BacktraceWrapper.h header file and add it to your GameInstance.
-
To initialize the Backtrace client, use
BacktraceIO::FInitializeBacktraceClient
.noteIt's recommended to initialize the client from the
GameInstance::OnStart()
method. However, if the method is not available, you can initialize the client with any method you use to start your app or game process.noteOptionally, you can specify custom attributes and file attachment paths to submit with your error reports. If you choose to specify file attachment paths, they must be specified as Android paths. For example, to specify a file attachment path for your
ProjectSavedDir()
, use:if (Target.Platform == UnrealTargetPlatform.Android)
#include "Misc/App.h"
#if PLATFORM_ANDROID
extern FString GFilePathBase;
FString FileAttachmentPath = GFilePathBase + FString("/UE4Game/") + FApp::GetName() + TEXT("/") + FApp::GetName() + TEXT("/Saved") + TEXT("MyFileName.txt");
#endifFor more details on how to convert your Unreal Engine paths to Android paths, see the conversion functions for
FAndroidPlatformFile::PathToAndroidPaths
in theAndroidPlatformFile.cpp
file.
BacktraceAndroid_UPL.xml
file. For more information, see Configuring Backtrace for Android for the backtrace-android library.-
From Assets, download and extract the
Backtrace.framework.zip
and theBacktrace_PLCrashReporter.framework.zip
files. -
Copy and paste the
Backtrace.framework.zip
and theBacktrace_PLCrashReporter.framework.zip
folders into the directory for your Unreal Engine project. -
Locate your app or game's
Build.cs
file. -
In the
Build.cs
file, add the following lines at the end of theModuleRules
class constructor:if (Target.Platform == UnrealTargetPlatform.IOS)
{
PublicAdditionalFrameworks.AddRange(
new Framework[]
{
new Framework("Backtrace", "/Library/Frameworks/Backtrace.framework", "", true),
new Framework("Backtrace_PLCrashReporter", "/Library/Frameworks/Backtrace_PLCrashReporter.framework", "", true)
}
);
}
Make sure to reflect the path to where you've placed both frameworks in your game project.
-
To initialize the Backtrace client, use the following to import
Backtrace-Swift.h
fromBacktrace.framework/Headers
:#if PLATFORM_IOS
#import <Backtrace/Backtrace-Swift.h>
#endif
void UYourGameInstanceBase::OnStart()
{
#if PLATFORM_IOS
BacktraceCredentials *credentials = [[BacktraceCredentials alloc]
initWithSubmissionUrl: [NSURL URLWithString: @"https://submit.backtrace.io/{subdomain}/{submission-token}/plcrash"]];
BacktraceClientConfiguration *configuration = [[BacktraceClientConfiguration alloc]
initWithCredentials: credentials
dbSettings: [[BacktraceDatabaseSettings alloc] init]
reportsPerMin: 3
allowsAttachingDebugger: NO
detectOOM: TRUE];
BacktraceClient.shared = [[BacktraceClient alloc] initWithConfiguration: configuration error: nil];
#endif
} -
For the
initWithSubmissionUrl
, provide the name of your subdomain and a submission token.
-Unattendded
can be added to the launch options for the game. This option sends crash reports without user intervention or knowledge, like the Windows client normally allows.Upload Debug Symbols
You must now ensure your build environment has been configured to generate debug symbols, which can then be uploaded to your Backtrace instance, a connected Symbol Server, an Amazon S3 bucket, or a Google Cloud storage bucket.
For information on how to generate symbols, see Symbolication.
Verify the Setup
At this point, you've installed and setup the Backtrace client to automatically capture crashes in your Unreal Engine game or app.
To test the integration, send a crash report to your Backtrace instance.
- Windows
- Android
- iOS
- macOS
- Linux
- Game Consoles
- Steam Deck
-
MyActor.h
:// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GenericPlatform/GenericPlatformCrashContext.h"
#include "MyActor.generated.h"
UCLASS()
class BACKTRACE_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION(BlueprintCallable, Category = "Backtrace Tools")
void DoCrashMe();
}; -
MyActor.cpp
:// Fill out your copyright notice in the Description page of Project Settings.
#include "MyActor.h"
// Sets default values
AMyActor::AMyActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();
{
FGenericCrashContext::SetGameData(TEXT("BluePrintCallStack"), TEXT("BluePrintCallStackValue"));
}
}
// Called every frame
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AMyActor::DoCrashMe()
{
UE_LOG(LogTemp, Fatal, TEXT("I crash and burn. Bye bye now"));
}
- Java:
try {
// throw exception here
}
catch (Exception exception) {
backtraceClient.send(new BacktraceReport(e));
} - Kotlin:
try {
// throw exception here
}
catch (e: Exception) {
backtraceClient.send(BacktraceReport(e))
}
-
Swift:
import UIKit
import Backtrace
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let backtraceCredentials = BacktraceCredentials(endpoint: URL(string: "https://backtrace.io")!,
token: "token")
BacktraceClient.shared = try? BacktraceClient(credentials: backtraceCredentials)
do {
try throwingFunc()
} catch {
BacktraceClient.shared?.send { (result) in
print(result)
}
}
return true
}
} -
Objective-C:
#import "AppDelegate.h"
@import Backtrace;
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
BacktraceCredentials *credentials = [[BacktraceCredentials alloc]
initWithEndpoint: [NSURL URLWithString: @"https://backtrace.io"]
token: @"token"];
BacktraceClient.shared = [[BacktraceClient alloc] initWithCredentials: credentials error: nil];
// sending NSException
@try {
NSArray *array = @[];
NSObject *object = array[1]; // will throw exception
} @catch (NSException *exception) {
[[BacktraceClient shared] sendWithException: exception completion:^(BacktraceResult * _Nonnull result) {
NSLog(@"%@", result);
}];
} @finally {
}
return YES;
}
@end
MyActor
and reference a blueprint. The blueprint can be attached to the BeginPlay
event.The header file (with the .h extension) contains the class definitions and functions, while the .cpp file defines the class implementation. For example:-
MyActor.h
:// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GenericPlatform/GenericPlatformCrashContext.h"
#include "MyActor.generated.h"
UCLASS()
class BACKTRACE_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION(BlueprintCallable, Category = "Backtrace Tools")
void DoCrashMe();
}; -
MyActor.cpp
:// Fill out your copyright notice in the Description page of Project Settings.
#include "MyActor.h"
// Sets default values
AMyActor::AMyActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();
{
FGenericCrashContext::SetGameData(TEXT("BluePrintCallStack"), TEXT("BluePrintCallStackValue"));
}
}
// Called every frame
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AMyActor::DoCrashMe()
{
UE_LOG(LogTemp, Fatal, TEXT("I crash and burn. Bye bye now"));
}