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

ios: fix isLowerPowerModeEnabled deadlock crash #94

Merged
merged 4 commits into from
Nov 1, 2024

Conversation

Augustyniak
Copy link
Contributor

@Augustyniak Augustyniak commented Nov 1, 2024

iOS 15.x (I think up to 15.2) crashes due to a deadlock when the following situation occurs:

  1. We access ProcessInfo.processInfo.isLowPowerModeEnabled
  2. ProcessInfo posts Notification.Name.NSProcessInfoPowerStateDidChange notification in a synchronous way from within isLowePowerModeEnabled getter.
  3. We access ProcessInfo.processInfo.isLowPowerModeEnabled from within Notification.Name.NSProcessInfoPowerStateDidChange notification.

The issue is caused by a bug in iOS 15 (which was fixed in later releases), so there is no perfect solution for this. My approach minimizes the risk of a crash by reducing the number of times we access ProcessInfo.processInfo.isLowPowerModeEnabled by over 99%. In practice, this should resolve the issue that our customers experienced.

One thing to note: I confirmed that this crash does not always occur on the first access of the ProcessInfo.processInfo.isLowPowerModeEnabled property.

Fixes BIT-4031

Stacktrace:

Crashed: io.bitdrift.capture.io.ResourceUtilizationTarget
0  libsystem_platform.dylib       0x60b8 _os_unfair_lock_recursive_abort + 36
1  libsystem_platform.dylib       0xa10 _os_unfair_lock_lock_slow + 304
2  Foundation                     0x28cf0 -[NSProcessInfo(NSProcessInfoHardwareState) isLowPowerModeEnabled] + 68
3  iCabbiDriver                   0xd5c628 DeviceStateListener.didReceiveNotification(_:) + 3725020
4  iCabbiDriver                   0xd5c1d4 closure #1 in closure #1 in closure #1 in DeviceStateListener.start() + 3723912
5  iCabbiDriver                   0x7104a4 thunk for @escaping @callee_guaranteed @Sendable (@in_guaranteed Notification) -> () + 4337403044 (<compiler-generated>:4337403044)
6  Foundation                     0x34b80 -[__NSObserver _doit:] + 348
7  CoreFoundation                 0x2aed8 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 28
8  CoreFoundation                 0xc6b8c ___CFXRegistrationPost_block_invoke + 52
9  CoreFoundation                 0x99f44 _CFXRegistrationPost + 456
10 CoreFoundation                 0x40d44 _CFXNotificationPost + 716
11 Foundation                     0x1a628 -[NSNotificationCenter postNotificationName:object:userInfo:] + 96
12 Foundation                     0x933e4 NSProcessInfoNotifyPowerState + 188
13 Foundation                     0x28d28 -[NSProcessInfo(NSProcessInfoHardwareState) isLowPowerModeEnabled] + 124
14 iCabbiDriver                   0xd61d88 LowPowerStateProvider.makeSnapshot() + 3747388
15 iCabbiDriver                   0xd61dc4 protocol witness for ResourceSnapshotProvider.makeSnapshot() in conformance LowPowerStateProvider + 3747448
16 iCabbiDriver                   0xd5fed4 closure #1 in ResourceUtilizationTarget.tick() + 3739528
17 iCabbiDriver                   0x404db8 thunk for @escaping @callee_guaranteed @Sendable () -> () + 4334210488 (<compiler-generated>:4334210488)
18 libdispatch.dylib              0x2914 _dispatch_call_block_and_release + 32
19 libdispatch.dylib              0x4660 _dispatch_client_callout + 20
20 libdispatch.dylib              0xbde4 _dispatch_lane_serial_drain + 672
21 libdispatch.dylib              0xc98c _dispatch_lane_invoke + 444
22 libdispatch.dylib              0xbcbc _dispatch_lane_serial_drain + 376
23 libdispatch.dylib              0xc98c _dispatch_lane_invoke + 444
24 libdispatch.dylib              0x171a8 _dispatch_workloop_worker_thread + 656
25 libsystem_pthread.dylib        0x10f4 _pthread_wqthread + 288
26 libsystem_pthread.dylib        0xe94 start_wqthread + 8

@Augustyniak Augustyniak requested a review from Reflejo November 1, 2024 18:21
@Augustyniak Augustyniak enabled auto-merge (squash) November 1, 2024 18:54
@Augustyniak Augustyniak merged commit 1c77b4a into main Nov 1, 2024
14 checks passed
@Augustyniak Augustyniak deleted the potentially-fix-isLowPowerMode-deadlock-crash branch November 1, 2024 19:05
@github-actions github-actions bot locked and limited conversation to collaborators Nov 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants