iOS:调试神秘的 CFNetwork <redacted> 在后台获取期间在 com.apple.NSURLConnectionLoader 线程上崩溃

iOS: Debugging mysterious CFNetwork <redacted> crash on com.apple.NSURLConnectionLoader thread during background fetch

我已经开始在一些生产设备上看到这种崩溃。 Fabric Crashlytics 和 iOS 提供的信息在这种情况下非常有限,我不确定如何调试它。

唯一常见的崩溃是发生在 iPhone 5S / iOS 10.2.1,但这可能只是巧合。

值得一提的是,我正在使用 Alamofire (4.3.0),其中 a similar problem 应该已经修复。

崩溃日志:

EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000020

Crashed: com.apple.NSURLConnectionLoader
0  libobjc.A.dylib                0x189c400a0 objc_retain + 16
1  CFNetwork                      0x18b92d1d4 <redacted> + 240
2  CFNetwork                      0x18b888e68 <redacted> + 348
3  CFNetwork                      0x18b95dc80 <redacted> + 104
4  CFNetwork                      0x18b95dc0c <redacted> + 36
5  CFNetwork                      0x18b8f32ac <redacted> + 332
6  CFNetwork                      0x18b8f3120 <redacted> + 60
7  CFNetwork                      0x18b8f30b8 <redacted> + 268
8  CFNetwork                      0x18b865040 <redacted> + 116
9  CFNetwork                      0x18b7f7290 <redacted> + 48
10 CFNetwork                      0x18b7f71c4 <redacted> + 220
11 CFNetwork                      0x18b7f5550 <redacted> + 128
12 CFNetwork                      0x18b92ca7c <redacted> + 1904
13 CFNetwork                      0x18b92c23c <redacted> + 144
14 CFNetwork                      0x18b92e18c <redacted> + 28
15 libdispatch.dylib              0x18a07a1bc _dispatch_client_callout + 16
16 libdispatch.dylib              0x18a085ab0 _dispatch_block_invoke_direct + 376
17 CFNetwork                      0x18ba2a598 <redacted> + 36
18 CoreFoundation                 0x18b0c9c18 CFArrayApplyFunction + 68
19 CFNetwork                      0x18ba2a47c <redacted> + 136
20 CFNetwork                      0x18ba2b7a4 <redacted> + 312
21 CFNetwork                      0x18ba2b510 <redacted> + 64
22 CoreFoundation                 0x18b19eb5c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
23 CoreFoundation                 0x18b19e4a4 __CFRunLoopDoSources0 + 524
24 CoreFoundation                 0x18b19c0a4 __CFRunLoopRun + 804
25 CoreFoundation                 0x18b0ca2b8 CFRunLoopRunSpecific + 444
26 CFNetwork                      0x18b8cfa70 <redacted> + 336
27 Foundation                     0x18bd04e68 __NSThread__start__ + 1024
28 libsystem_pthread.dylib        0x18a285850 <redacted> + 240
29 libsystem_pthread.dylib        0x18a285760 _pthread_start + 282
30 libsystem_pthread.dylib        0x18a282d94 thread_start + 4

更新:

添加额外的日志记录后,我发现崩溃是在 后台应用程序刷新 期间发生的。根据documentation "app has up to 30 seconds of wall-clock time to perform the download operation and call the specified completion handler block".

但是,我可以在日志中看到 崩溃同时发生(同一秒 - 我在崩溃日志中看不到毫秒数)作为请求被解雇。换句话说,系统调用 func application(_ application:, performFetchWithCompletionHandler: 和崩溃之间几乎没有时间。

因此,这不应该是系统因为在后台执行时间过长而杀死应用程序的情况。

这与 AlamoFire 无关。 NSURLSession 和 NSURLConnection 堆栈非常复杂,并且大部分是基于 CoreFoundation 用 C 编写的,这意味着它们也没有获得 ARC 的好处。很有可能,这是堆栈深处某处的一个微妙的多线程错误,仅在某些情况下才会发生,并且可能高度依赖于时间。

在这种特殊情况下,一个对象已被清零(可能是由于某个地方的弱引用归零)并且 CF 堆栈的某些部分仍在使用它,并尝试取消引用该对象以使用 C 级保留它API,导致 NULL 指针取消引用。

更具体地说,您可能会遇到此崩溃:https://github.com/PhilipsHue/PhilipsHueSDK-iOS-OSX/issues/52

至于避免它,你不太可能成功。最好的办法是确保您的应用正确保存状态并从冷启动中尽快重新启动,这样冷启动和热启动之间的区别就无关紧要了。

就是说,您可能会尝试的一件事是,一旦收到通知您将进入后台,就立即取消所有未完成的前台连接,然后在 discretionary 设置为 YES 的会话中重新启动它们.