Skip to content

iOS Unity Wrapper: Crash when UnitySendMessage called from background thread (SKAN callbacks) #40

@DFC005

Description

@DFC005

SDK Version: Latest (5.6.0)
Unity Version: Unity 6.0 (6000.0.62f1)

Summary

We are seeing crashes in production caused by UnitySendMessage being invoked from a background thread inside SingularUnityWrapper.mm.

Specifically, SKAdNetwork-related callbacks appear to execute on a background dispatch queue, and the wrapper directly calls UnitySendMessage without dispatching to the main thread.

This results in crashes inside Unity’s internal NativeSendMessage / BackgroundJobQueue.

Crash Stack

Crashed: com.apple.root.default-qos
0  UnityFramework  BackgroundJobQueue::CreateMainThreadGroup()
1  UnityFramework  BackgroundJobQueue::ScheduleMainThreadJobInternal
2  UnityFramework  BackgroundJobQueue::ScheduleMainThreadJobInternal
3  UnityFramework  NativeSendMessage::AddMessage
4  UnityFramework  __StartSingularSession__block_invoke_2 (SingularUnityWrapper.mm:91)
5  UnityFramework  __59+[SkanManager valuesHasBeenUpdated:coarseValue:lockWindow:]_block_invoke
6  libdispatch.dylib  _dispatch_call_block_and_release

The crash originates from:

SingularUnityWrapper.mm:91

which ultimately calls:

UnitySendMessage("SingularSDKObject", methodName, result);

Problem

In the current wrapper implementation:

static void sendSdkMessage(const char *methodName, NSString *param) {
    ...
    UnitySendMessage("SingularSDKObject", methodName, result);
}

There is:

❌ No dispatch to the main thread

❌ No lifecycle gating (Unity ready / quitting)

❌ No protection against background SKAN callbacks

❌ Memory leak (malloc without free)

When SKAN conversion callbacks are invoked on a background queue:

singularConfig.conversionValuesUpdatedCallback = ^(...)

they eventually call UnitySendMessage off-main-thread.

Unity does not guarantee thread safety for UnitySendMessage and this can cause crashes during:

  • App startup
  • App backgrounding
  • App termination
  • Early Unity initialisation windows

Expected Behaviour

The Unity wrapper should:

  1. Dispatch all UnitySendMessage calls onto the main queue.
  2. Optionally guard against calls during app teardown.
  3. Avoid leaking malloc'ed strings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions