dd-sdk-reactnative
dd-sdk-reactnative copied to clipboard
Datadog Session Replay crash on iOS when recording a date picker
We have consistently encountered a crash caused by the react-native-session-replay library when interacting with a date picker on iOS. Our application hangs and eventually crashes. Based on the stack trace, the ViewTreeRecorder.recordRecursively method seems trapped in a recursive loop.
We have experienced this crash on multiple iOS versions, specifically from iOS 18 to 18.4. We also tried upgrading to dd-sdk-reactnative/releases/tag/2.6.6, but the problem persists.
Tech stack:
- node 18.18.1
- react-native: 0.73.6
- Expo: 50.0.20
- Expo Datadog: 50.2.0
- @datadog/datadog-ci: 2.45.1
- @datadog/mobile-react-native: 2.6.1
- @datadog/mobile-react-native-session-replay: 2.6.1
- @datadog/mobile-react-navigation: 2.6.1
View stacktrace
CrashReporter Key: cd88fe4ec5a73a5f81f1bda8afb7e496bbc94f28
Hardware Model: iPhone13,3
Process: [REDACTED]
Identifier: [REDACTED_APP_NAME]
Version: 3.5.2
Role: Foreground
OS Version: iOS 18.3.2
App Hang: The app was terminated while unresponsive
0 libsystem_kernel.dylib +0x14e0 _kevent_id
1 libdispatch.dylib +0x26b3c __dispatch_kq_poll
2 libdispatch.dylib +0x27548 __dispatch_event_loop_wait_for_ownership
3 libdispatch.dylib +0x13ac8 ___DISPATCH_WAIT_FOR_QUEUE__
4 libdispatch.dylib +0x13690 __dispatch_sync_f_slow
5 [REDACTED_APP_NAME] +0x3199ec RCTTextViewRecorder.semantics(of:with:in:) (RCTTextViewRecorder.swift:55:32)
6 [REDACTED_APP_NAME] +0x31a000 protocol witness for SessionReplayNodeRecorder.semantics(of:with:in:) in conformance RCTTextViewRecorder (<compiler-generated>)
7 [REDACTED_APP_NAME] +0x3976ec ViewTreeRecorder.nodeSemantics(for:with:in:) (ViewTreeRecorder.swift:71:52)
8 [REDACTED_APP_NAME] +0x3973b8 ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:50:25)
9 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
10 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
11 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
12 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
13 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
14 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
15 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
16 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
17 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
18 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
19 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
20 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
21 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
22 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
23 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
24 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
25 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
26 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
27 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
28 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
29 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
30 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
31 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
32 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
33 [REDACTED_APP_NAME] +0x39756c ViewTreeRecorder.recordRecursively(nodes:view:context:overrides:) (ViewTreeRecorder.swift:60:17)
34 [REDACTED_APP_NAME] +0x39aa10 ViewTreeRecorder.record(_:in:) (ViewTreeRecorder.swift:20:9)
35 [REDACTED_APP_NAME] +0x39e2cc WindowViewTreeSnapshotProducer.takeSnapshot(with:) (WindowViewTreeSnapshotProducer.swift:22:32)
36 [REDACTED_APP_NAME] +0x32eee0 protocol witness for ViewTreeSnapshotProducer.takeSnapshot(with:) in conformance WindowViewTreeSnapshotProducer (<compiler-generated>)
37 [REDACTED_APP_NAME] +0x330d88 protocol witness for Recording.captureNextRecord(_:) in conformance Recorder (<compiler-generated>)
38 [REDACTED_APP_NAME] +0x14ea74 closure #1 in objc_rethrow<A>(_:file:line:) (DDError.swift:128:29)
39 [REDACTED_APP_NAME] +0x33c64 thunk for @callee_guaranteed () -> () (<compiler-generated>)
40 [REDACTED_APP_NAME] +0x33c84 thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
41 [REDACTED_APP_NAME] +0xbb298 +[__dd_private_ObjcExceptionHandler catchException:error:] (ObjcExceptionHandler.m:14:9)
42 [REDACTED_APP_NAME] +0xd0044 implicit closure #1 in closure #1 in variable initialization expression of registerObjcExceptionHandlerOnce (DatadogCore.swift:526:63)
43 [REDACTED_APP_NAME] +0x14e844 objc_rethrow<A>(_:file:line:) (DDError.swift:126:27)
44 [REDACTED_APP_NAME] +0x3309f4 RecordingCoordinator.captureNextRecord() (RecordingCoordinator.swift:146:17)
45 [REDACTED_APP_NAME] +0x330280 closure #1 in RecordingCoordinator.init(scheduler:textAndInputPrivacy:imagePrivacy:touchPrivacy:rumContextObserver:srContextPublisher:recorder:sampler:telemetry:startRecordingImmediately:methodCallTelemetrySamplingRate:) (RecordingCoordinator.swift:61:51)
46 [REDACTED_APP_NAME] +0x32d47c thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
47 [REDACTED_APP_NAME] +0x32d314 closure #1 in closure #1 in closure #1 in MainThreadScheduler.start() (MainThreadScheduler.swift:53:57)
48 [REDACTED_APP_NAME] +0x35bd0 thunk for @escaping @callee_guaranteed @Sendable (@guaranteed NSTimer) -> () (<compiler-generated>)
49 Foundation +0x1d56d8 ___NSFireTimer
50 CoreFoundation +0xf0298 ___CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__
51 CoreFoundation +0xeff3c ___CFRunLoopDoTimer
52 CoreFoundation +0xefa90 ___CFRunLoopDoTimers
53 CoreFoundation +0x76100 ___CFRunLoopRun
54 CoreFoundation +0xc8280 _CFRunLoopRunSpecific
55 GraphicsServices +0x14bc _GSEventRunModal
56 UIKitCore +0x3ee670 -[UIApplication _run]
57 UIKitCore +0x14e84 _UIApplicationMain
58 [REDACTED_APP_NAME] +0x4668 main (main.m:14:12)
59 dyld +0x2fde4 start
Reproduction steps
Reproducible Expo demo application https://github.com/marcobeltempo/datadaog-session-replay-crash-demo
Volume
100
Affected SDK versions
2.6.1, 2.6.6
Latest working SDK version
N/A
Does the crash manifest in the latest SDK version?
Yes
React Native Version
0.73.6
Package.json Contents
No response
iOS Setup
No response
Android Setup
No response
Device Information
No response