Skip to content

IsMainThread check fails in burst context #2216

@bitsandfoxes

Description

@bitsandfoxes

Originates from https://discord.com/channels/621778831602221064/621778831602221072/1387406424404922561

Problem

Capturing an exception aborts the game with

UnityEngine::UnityException: GetBatteryStatus can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
This Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Burst -> Enable Compilation) to inspect full exceptions & stacktraces. In this standalone build configuration burst will now abort the Application.
Sentry.Unity.UnityEventProcessor:PopulateDevice(Device)
Sentry.Unity.UnityEventProcessor:SetEventContext(IEventLike)
Sentry.Unity.UnityEventProcessor:Process(SentryEvent)
Sentry.SentryClient:DoSendEvent(SentryEvent, SentryHint, Scope)
Sentry.SentryClient:CaptureEvent(SentryEvent, Scope, SentryHint)
Sentry.Internal.Hub:CaptureEvent(SentryEvent, SentryHint, Scope)
Sentry.Internal.Hub:CaptureEvent(SentryEvent, Scope, SentryHint)
Sentry.SentryClientExtensions:CaptureMessage(ISentryClient, String, SentryLevel)
Sentry.Unity.Integrations.UnityApplicationLoggingIntegration:OnLogMessageReceived(String, String, LogType)
[./Runtime/Jobs/ScriptBindings/JobsBindings.cpp]

Proposal

We're guarding the battery-status with a check here

if (!MainThreadData.IsMainThread())
{
return;
}
device.BatteryStatus = SystemInfo.batteryStatus.ToString();

but this seems to fail in a burst compiled setting.

We'll need to update the check with something like

bool IsMainThread() => !JobsUtility.IsExecutingJob && Thread.CurrentThread.ManagedThreadId == SynchronizationContext.mainThreadId;

Repro

[BurstCompile]
public struct BadCommandJob : IJob
{
    [BurstCompile]
    public void Execute()
    {
        Debug.Log($"Log from job. I can ruin your application!");
    }
}

And on the main thread call:

var job = new BadCommandJob();
job.Run();

Metadata

Metadata

Assignees

Labels

BugSomething isn't workingUnity

Type

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions