Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Perf] Fix MapTable race#16072

Merged
paulb777 merged 14 commits into
mainfirebase/firebase-ios-sdk:mainfrom
pb-fix-maptable-bugfirebase/firebase-ios-sdk:pb-fix-maptable-bugCopy head branch name to clipboard
Apr 16, 2026
Merged

[Perf] Fix MapTable race#16072
paulb777 merged 14 commits into
mainfirebase/firebase-ios-sdk:mainfrom
pb-fix-maptable-bugfirebase/firebase-ios-sdk:pb-fix-maptable-bugCopy head branch name to clipboard

Conversation

@paulb777

@paulb777 paulb777 commented Apr 10, 2026

Copy link
Copy Markdown
Member

Fix #14473

Based on the source changes in PR #16072, the fix addresses a crash related to NSMapTable by replacing it with a more manual, thread-safe implementation using NSMutableDictionary and NSLock.

Core Changes

The PR moves away from NSMapTable (configured with weak keys and strong values) in favor of a custom "Holder" pattern to manage UIViewController references and their associated performance traces.

  • Introduction of FPRScreenTraceHolder: A new internal class that holds a weak reference to the UIViewController and a strong reference to the FIRTrace.
  • Storage Shift: The activeScreenTraces property changed from an NSMapTable to a standard NSMutableDictionary<NSValue *, FPRScreenTraceHolder *>.
  • Thread Safety: Added activeScreenTracesLock (NSLock) to synchronize access to the dictionary, which was likely a contributor to the original crash.

Technical Analysis

  • Pointer Reuse Protection: The implementation now explicitly checks for "stale" entries. Since NSValue stores the raw pointer (non-retained), the code now verifies if (holder && holder.viewController != viewController) before starting or stopping a trace. This prevents a new view controller from accidentally inheriting a trace from a deallocated object that happened to share the same memory address.
  • Memory Management: By using a weak property in the FPRScreenTraceHolder, the SDK avoids retain cycles while still allowing the dictionary to be cleaned up when a view controller is dismissed or deallocated.
  • Stress Testing: The author added a robust concurrency test (testScreenTraceTrackerStress) that spawns multiple threads to hammer the appear/disappear/deallocate cycle simultaneously, ensuring the new locking mechanism holds up under pressure.

Observations

  1. Complexity Trade-off: While NSMapTable is designed to handle weak-to-strong mappings automatically, it is notoriously finicky regarding thread safety and when it actually "cleans up" nilled-out entries. This manual implementation is more verbose but significantly more predictable.
  2. Explicit Cleanup: In stopScreenTraceForViewController, the entry is now explicitly removed from the dictionary after the trace is stopped, which is cleaner than relying on the internal "garbage collection" of a map table.

@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

@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 transitions the screen trace tracking mechanism from NSMapTable to a thread-safe NSMutableDictionary protected by an NSLock, utilizing a new FPRScreenTraceHolder class. Review feedback identifies a critical risk of an NSInvalidArgumentException if a nil view controller is processed and notes a potential memory leak because NSMutableDictionary lacks the automatic cleanup behavior of weak-key NSMapTable. Additionally, a unit test was identified as having decreased rigor regarding memory management verification.

Comment thread FirebasePerformance/Sources/AppActivity/FPRScreenTraceTracker.m
Comment thread FirebasePerformance/Tests/Unit/FPRScreenTraceTrackerTest.m
@paulb777

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@paulb777

Copy link
Copy Markdown
Member Author

/gemini review

@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 addresses race condition crashes in FPRScreenTraceTracker by replacing the NSMapTable used for tracking active screen traces with a thread-safe NSMutableDictionary protected by an NSLock. It introduces a FPRScreenTraceHolder to manage weak references to view controllers and strong references to traces, and includes a cleanup mechanism for stale entries. Unit tests were updated to accommodate these changes, and a new stress test was added to verify thread safety. A review comment suggests improving a busy-wait loop in the tests to prevent potential infinite loops.

Comment thread FirebasePerformance/Tests/Unit/FPRScreenTraceTrackerTest.m Outdated
@paulb777
paulb777 force-pushed the pb-fix-maptable-bug branch from 0ded3bb to bf99bdd Compare April 10, 2026 16:21
@paulb777 paulb777 changed the title Fix MapTable bug [Perf] Fix MapTable bug Apr 10, 2026
@paulb777 paulb777 changed the title [Perf] Fix MapTable bug [Perf] Fix MapTable race Apr 10, 2026
@paulb777
paulb777 force-pushed the pb-fix-maptable-bug branch from 15b3ae7 to 03d2a3d Compare April 10, 2026 21:58
@paulb777

Copy link
Copy Markdown
Member Author

/gemini review

@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 addresses race condition crashes in FPRScreenTraceTracker by replacing NSMapTable with a thread-safe NSMutableDictionary protected by an NSLock. It also introduces an FPRScreenTraceHolder to manage trace associations and adds a cleanup mechanism for stale entries. I have provided feedback regarding the use of a safer polling mechanism in tests to avoid potential hangs, as well as suggestions to use NSRecursiveLock and optimize the locking sequence in the tracker for better atomicity.

Comment thread FirebasePerformance/Tests/Unit/FPRScreenTraceTrackerTest.m Outdated
Comment thread FirebasePerformance/Sources/AppActivity/FPRScreenTraceTracker.m Outdated
Comment thread FirebasePerformance/Sources/AppActivity/FPRScreenTraceTracker.m Outdated
@paulb777

Copy link
Copy Markdown
Member Author

/gemini review

@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 addresses race condition crashes in FPRScreenTraceTracker by replacing NSMapTable with a thread-safe NSMutableDictionary protected by an NSRecursiveLock. It introduces a FPRScreenTraceHolder class to manage weak references to view controllers and includes a cleanup mechanism for stale entries. Review feedback suggests simplifying the logic for handling pointer reuse during trace removal, using idiomatic array factory methods, and increasing the iteration count in the stress test to improve the reliability of concurrency checks.

Comment thread FirebasePerformance/Sources/AppActivity/FPRScreenTraceTracker.m Outdated
Comment thread FirebasePerformance/Sources/AppActivity/FPRScreenTraceTracker.m Outdated
Comment thread FirebasePerformance/Tests/Unit/FPRScreenTraceTrackerTest.m
@paulb777
paulb777 requested a review from ncooke3 April 11, 2026 14:44
@paulb777 paulb777 added this to the 12.13.0 - M180 milestone Apr 14, 2026
@paulb777
paulb777 merged commit 4474ae1 into main Apr 16, 2026
73 checks passed
@paulb777
paulb777 deleted the pb-fix-maptable-bug branch April 16, 2026 16:58
leojaygoogle pushed a commit that referenced this pull request Jun 29, 2026
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.

[GULNetworkURLSession setSessionInFetcherMap:forSessionID:] crash

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.