Skip to content

[ABT] Fix race crash - #16148

Merged
paulb777 merged 2 commits into
mainfrom
pb-abt-race
May 1, 2026
Merged

[ABT] Fix race crash#16148
paulb777 merged 2 commits into
mainfrom
pb-abt-race

Conversation

@paulb777

Copy link
Copy Markdown
Member

Fix #16145

Crash Analysis
The crash occurs due to a thread safety issue (race condition) when creating a copy of a mutable array on a background thread.

1. The Underlying Cause
The crash is a classic concurrency issue caused by
FIRExperimentController.m
asynchronously accessing a mutable array that is passed by the caller.

A. Asynchronous Execution in Firebase ABTesting
In FIRExperimentController.m, the updateExperimentsWithServiceOrigin:events:policy:lastStartTime:payloads:completionHandler: method dispatches the work to a background queue:

B. Mutation by the Caller (RCNConfigExperiment.m)
Even though the user's request states they are not using any A/B testing functionality, Firebase Remote Config internally uses Firebase ABTesting to process experiments (frc service origin).

In RCNConfigExperiment.m , the _experimentPayloads property is a mutable array (NSMutableArray<NSData >). During synchronization, Remote Config triggers an update:

C. Race Condition
updateExperimentsWithHandler: passes _experimentPayloads (NSMutableArray) to updateExperimentsWithServiceOrigin:.
FIRExperimentController captures a reference to this mutable array inside a dispatch_async block.
While the background thread starts executing, the main thread concurrently receives a new server payload and mutates the array (e.g., it clears all objects in updateExperimentsWithResponse: by calling [_experimentPayloads removeAllObjects]).
As the background thread reaches line 51 of FIRExperimentController.m (NSArray *payloadsCopy = [payloads copy]), it executes initWithArray:range:copyItems:. It reads the array's count and tries to obtain the objects. Because the array was cleared by the main thread, it tries to read a range that is out of the new bounds of the empty array, resulting in the crash: *** -[__NSArrayM getObjects:range:]: range {0, 1} extends beyond bounds for empty array

2. The Fix
To fix this crash, FIRExperimentController must create an immutable copy of the payloads array synchronously on the calling thread before passing it to the background queue.

@gemini-code-assist

Copy link
Copy Markdown
Contributor
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

@paulb777

Copy link
Copy Markdown
Member Author

/gemini review

@paulb777

Copy link
Copy Markdown
Member Author

Closing in favor of #16147

@paulb777 paulb777 closed this Apr 30, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes a crash caused by a race condition on the mutable payloads array in FIRExperimentController. It achieves this by creating an immutable copy of the payloads array before passing it into an asynchronous dispatch block, ensuring thread safety. The CHANGELOG has been updated to reflect this fix. I have no feedback to provide.

Comment thread FirebaseABTesting/CHANGELOG.md Outdated
@ncooke3 ncooke3 reopened this Apr 30, 2026
Co-authored-by: Nick Cooke <36927374+ncooke3@users.noreply.github.com>
@paulb777
paulb777 merged commit 6957b76 into main May 1, 2026
54 checks passed
@paulb777
paulb777 deleted the pb-abt-race branch May 1, 2026 04:07
leojaygoogle pushed a commit that referenced this pull request Jun 29, 2026
Co-authored-by: Nick Cooke <36927374+ncooke3@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash: ABTExperimentsToSetFromPayloads + 88 (FIRExperimentController.m:51)

2 participants