Skip to content

Commit 8cd1532

Browse files
authored
feat(unreal): Application hang tracking (#16814)
This PR adds documentation for application hang tracking feature in Unreal SDK. Related items: - getsentry/sentry-unreal#1270
1 parent 664ac68 commit 8cd1532

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
title: App Hangs
3+
sidebar_order: 11
4+
description: "Learn how to detect and report application hangs in your Unreal Engine game."
5+
---
6+
7+
Application hang errors are triggered when a thread monitored by Unreal Engine's heartbeat system becomes unresponsive for longer than a configurable timeout. The Unreal SDK reports hang errors as Sentry events.
8+
9+
Trying to play an unresponsive game is extremely frustrating for users. There are many reasons why an app may become unresponsive, such as long-running computations on the game thread, infinite loops, deadlocks, and so on. With app hang tracking you can detect and fix them.
10+
11+
<Alert>
12+
13+
This feature is available on Windows and Linux only. On macOS and iOS, the Cocoa SDK provides its own <PlatformLink to="/configuration/options/#enableAppNotRespondingTracking">app hang detection</PlatformLink>. On Android, the Java SDK provides its own <PlatformLink to="/configuration/options/#enableAppNotRespondingTracking">ANR detection</PlatformLink>.
14+
15+
</Alert>
16+
17+
## How It Works
18+
19+
The SDK hooks into Unreal Engine's built-in `FThreadHeartBeat` system, which monitors threads that participate in the engine's heartbeat (game thread, render thread, audio thread, etc.):
20+
21+
1. The engine runs a background thread that periodically checks whether monitored threads are still sending heartbeats.
22+
2. When a thread misses heartbeats for longer than the engine's `StuckDuration` (default 1 second), the engine fires an `OnThreadStuck` delegate.
23+
3. The SDK's watchdog thread then waits for the remaining time up to the configured hang timeout.
24+
4. If the thread is still unresponsive when the timeout expires, the SDK captures a hang event with the stuck thread's stack trace and sends it to Sentry.
25+
5. If the thread recovers before the timeout, the hang is not reported.
26+
27+
The hang event includes:
28+
- Event level: `error`
29+
- Exception type: `App Hanging`
30+
- Exception value: `Application not responding`
31+
- Mechanism type: `AppHang`
32+
- Stack trace of the hung thread
33+
34+
## Prerequisites
35+
36+
The engine's heartbeat monitor thread must be enabled for hang tracking to work. By default, `HangDuration` in `[Core.System]` is set to `0`, which disables the heartbeat monitor. Set it to a value greater than `0` in your project's `DefaultEngine.ini`:
37+
38+
```ini {filename:DefaultEngine.ini}
39+
[Core.System]
40+
HangDuration=25
41+
```
42+
43+
`HangDuration` is the threshold (in seconds) after which the engine reports a hang to the [Crash Reporter Client](/platforms/unreal/configuration/setup-crashreporter/). The Sentry SDK's hang tracking coexists with the engine's mechanism — the SDK hooks into the heartbeat system independently and captures its own events based on the <PlatformLink to="/configuration/app-hangs/#hang-timeout">hang timeout</PlatformLink> you configure.
44+
45+
## Configuration
46+
47+
App hang tracking is disabled by default. To enable it, navigate to **Project Settings > Plugins > Sentry > General > Native** and toggle **Enable hang tracking**.
48+
49+
Alternatively, add the following to your project's configuration file:
50+
51+
```ini {filename:DefaultEngine.ini}
52+
[/Script/Sentry.SentrySettings]
53+
EnableHangTracking=True
54+
```
55+
56+
### Hang Timeout
57+
58+
The hang timeout controls how long a thread must be unresponsive before a hang event is captured. The default is 5 seconds, with a minimum of 1 second.
59+
60+
You can adjust it in **Project Settings > Plugins > Sentry > General > Native > Hang timeout (seconds)**, or via the configuration file:
61+
62+
```ini {filename:DefaultEngine.ini}
63+
[/Script/Sentry.SentrySettings]
64+
HangTimeoutDuration=5.0
65+
```
66+
67+
If the configured timeout is shorter than the engine's `StuckDuration`, it will be automatically adjusted upward to match, since the SDK can only start tracking after the engine reports a thread as stuck.
68+
69+
## Filtering Hang Events
70+
71+
You can filter or modify hang events using the `BeforeSend` callback. The `USentryEvent` class provides an `IsAnr()` method that returns `true` for hang events (exception type `App Hanging`):
72+
73+
```cpp
74+
UCLASS()
75+
class UHangFilterHandler : public USentryBeforeSendHandler
76+
{
77+
GENERATED_BODY()
78+
79+
public:
80+
virtual USentryEvent* HandleBeforeSend_Implementation(USentryEvent* Event, USentryHint* Hint) override
81+
{
82+
if (Event->IsAnr())
83+
{
84+
// Modify or return nullptr to discard the event
85+
}
86+
return Event;
87+
}
88+
};
89+
```
90+
91+
## Limitations
92+
93+
- **Packaged builds only**: Hang tracking does not work in the editor or in debug build configurations. The engine's `USE_HANG_DETECTION` macro must be enabled, which is only the case in packaged non-debug builds.
94+
- **No early-startup detection**: Hangs that occur before `FEngineLoop::Tick()` starts (e.g. during `GameInstance::Init()`) are not detected, because threads must have sent at least one heartbeat before they can be monitored.
95+
- **Requires engine configuration**: The `HangDuration` setting in `[Core.System]` must be set to a value greater than `0`. Without it, the engine's heartbeat monitor thread doesn't run.
96+
- **One thread at a time**: If multiple threads become stuck simultaneously, only one hang is reported per episode. The engine's `FThreadHeartBeat` reports one stuck thread at a time, so additional stuck threads are only detected after the first one recovers.

docs/platforms/unreal/configuration/options.mdx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,28 @@ This feature is supported on Windows and Linux only.
181181

182182
</SdkOption>
183183

184+
<SdkOption name="EnableHangTracking" type="bool" defaultValue="false">
185+
186+
Tracks application hangs (unresponsive threads) using Unreal Engine's built-in `FThreadHeartBeat`. When enabled, the SDK launches a watchdog thread that monitors engine heartbeat delegates and captures a hang event if a thread remains unresponsive for longer than the configured timeout.
187+
188+
This option is turned off by default.
189+
190+
<Alert>
191+
192+
This feature is available on Windows and Linux only, and only works in packaged non-debug builds. See <PlatformLink to="/configuration/app-hangs/">App Hangs</PlatformLink> for setup details and prerequisites.
193+
194+
</Alert>
195+
196+
</SdkOption>
197+
198+
<SdkOption name="HangTimeoutDuration" type="float" defaultValue="5.0">
199+
200+
Duration in seconds that a thread must be unresponsive before a hang event is captured. The minimum value is `1.0` second. If set below the engine's `StuckDuration` (default 1 second), it is automatically adjusted upward.
201+
202+
Only takes effect when <PlatformIdentifier name="EnableHangTracking" /> is enabled.
203+
204+
</SdkOption>
205+
184206
## Hooks
185207

186208
These options can be used to hook the SDK in various ways to customize the reporting of events.

0 commit comments

Comments
 (0)