Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RNGestureHandlerModule.mm fatally throws NSGenericException in iOS production due to collection mutating while being enumerated #2658

Closed
sh-pq opened this issue Oct 26, 2023 · 4 comments · Fixed by #2687
Labels
Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snack or repo is provided

Comments

@sh-pq
Copy link

sh-pq commented Oct 26, 2023

Description

We use GestureDetector in our application inside the contents of an inverted FlatList. Within that context, we're observing GestureDetector throw a fatal exception (stack trace below) that crashes the application. The fatal error originates from RNGestureHandlerModule.mm line 259.

  • This was reproduced on 2.13.0 and then 2.13.2, the only two versions we've used so far.
  • The errors aren't 100% deterministic but we can reproduce it frequently during our tests.
  • We only observe the error being thrown on production releases in iOS. (In case it matters, they're testflight releases; we haven't released any version of the application with this dependency to the store yet.) Debug iOS, and debug + production Android, are all fine.
  • Errors occur from simply loading the component, through scrolling the list, or through pressing or long pressing within the gesture detector.

MVCE notes

I have attached a MVCE but I have some notes to make about it.

  • We use React Native Stack Navigation, and the component containing the FlatList is a screen inside the navigation, but I'm not sure how crucial it is to the MVCE so I've left it out.
  • There's one bit missing from the MVCE: the FlatList there doesn't scroll, and I don't remember what I should be doing to get it to scroll — it's been weeks since I last wrote the scrolling FlatList in this area and I'm not sure what bit I'm missing that'd make it scroll.

Stack trace

Here Lambda is the name of our application.

Fatal Exception: NSGenericException

*** Collection <__NSArrayM: 0x283e03b70> was mutated while being enumerated.

Fatal Exception: NSGenericException
0  CoreFoundation                 0x9cb4 __exceptionPreprocess
1  libobjc.A.dylib                0x183d0 objc_exception_throw
2  CoreFoundation                 0x176920 -[__NSSingleObjectEnumerator init]
3  Lambda                         0x6cf580 -[RNGestureHandlerModule didMountComponentsWithRootTag:] + 259 (RNGestureHandlerModule.mm:259)
4  Lambda                         0x6704a0 -[RCTSurfacePresenter mountingManager:didMountComponentsWithRootTag:] + 453 (RCTSurfacePresenter.mm:453)
5  Lambda                         0x651f94 std::__1::__function::__func<-[RCTMountingManager performTransaction:]::$_2, std::__1::allocator<-[RCTMountingManager performTransaction:]::$_2>, void (facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&)>::operator()(facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&) + 282 (RCTMountingManager.mm:282)
6  Lambda                         0x88f118 facebook::react::TelemetryController::pullTransaction(std::__1::function<void (facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&)> const&, std::__1::function<void (facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&)> const&, std::__1::function<void (facebook::react::MountingTransaction const&, facebook::react::SurfaceTelemetry const&)> const&) const + 46 (TelemetryController.cpp:46)
7  Lambda                         0x650ca4 -[RCTMountingManager performTransaction:] + 468 (function.h:468)
8  Lambda                         0x650bf8 -[RCTMountingManager initiateTransaction:] + 260 (RCTMountingManager.mm:260)
9  libdispatch.dylib              0x2320 _dispatch_call_block_and_release
10 libdispatch.dylib              0x3eac _dispatch_client_callout
11 libdispatch.dylib              0x126a4 _dispatch_main_queue_drain
12 libdispatch.dylib              0x122f4 _dispatch_main_queue_callback_4CF
13 CoreFoundation                 0x98c28 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
14 CoreFoundation                 0x7a560 __CFRunLoopRun
15 CoreFoundation                 0x7f3ec CFRunLoopRunSpecific
16 GraphicsServices               0x135c GSEventRunModal
17 UIKitCore                      0x39cf58 -[UIApplication _run]
18 UIKitCore                      0x39cbbc UIApplicationMain
19 Lambda                         0x864c main + 8 (main.m:8)
20 ???                            0x1ad2c0dec (Missing)

Steps to reproduce

  1. Have an inverted FlatList
  2. Have the components contain GestureDetector
  3. Release it on iOS in Production mode
  4. Interact with it. Visit the page (inside a navigator), scroll the FlatList, etc.
  5. Observe crashes occur on load, or during presses, scrolls, or other interactions.

Snack or a link to a repository

Gesture Handler version

2.13.2

React Native version

0.72.5

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

Fabric (New Architecture)

Build type

Release mode

Device

Real device

Device model

iPhone 12 Pro, iPhone 13 Pro Max (and every other iOS device we've tested but for which I don't have the model numbers at present)

Acknowledgements

Yes

@github-actions github-actions bot added Repro provided A reproduction with a snack or repo is provided Platform: iOS This issue is specific to iOS labels Oct 26, 2023
@sh-pq sh-pq changed the title GestureDetector throws Fatal Exception NSGenericException in iOS production due to collection mutating while being enumerated RNGestureHandlerModule.mm throws Fatal Exception NSGenericException in iOS production due to collection mutating while being enumerated Oct 26, 2023
@sh-pq sh-pq changed the title RNGestureHandlerModule.mm throws Fatal Exception NSGenericException in iOS production due to collection mutating while being enumerated RNGestureHandlerModule.mm fatally throws NSGenericException in iOS production due to collection mutating while being enumerated Oct 26, 2023
@j-piasecki
Copy link
Member

I wasn't able to reproduce the crash based on your snippet, but after looking through the code, it seems like the operations field is accessed from two different threads on the new arch, which could be explaining your crash. Could you check if the following patch solves the problem in your case?

react-native-gesture-handler+2.13.4.patch

@sh-pq
Copy link
Author

sh-pq commented Nov 15, 2023

@j-piasecki We're testing with that patch in a few days and will let you know what we see.

@j-piasecki
Copy link
Member

@sh-pq Do you maybe have any update on this?

@sh-pq
Copy link
Author

sh-pq commented Dec 1, 2023

@j-piasecki Outlook good; that patch seems to have fixed it. QA has been testing in production for more than a week with that patch and we haven't seen the crash even once in that time. Previously we'd see it very frequently and reliably within a short time of using the app.

j-piasecki added a commit that referenced this issue Jan 10, 2024
## Description

Removes usage of `didMountComponentsWithRootTag` on the new
architecture. It was doing exactly the same thing as `flushOperations`
but was executed on a different thread, which could cause crashes.
Removing this method shouldn't change any behavior as `flushOperations`
is scheduled after every operation.

Closes
#2658
 
## Test plan

See
#2658
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snack or repo is provided
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants