iOS: отладка загадочного ‹отредактировано› сбоя CFNetwork в потоке com.apple.NSURLConnectionLoader во время фоновой выборки

Я начал видеть этот сбой на нескольких устройствах в производстве. Информация, предоставляемая Fabric Crashlytics и iOS, в этом случае очень ограничена, и я не знаю, как ее отлаживать.

Единственное, что характерно для сбоев, это произошло на iPhone 5S / iOS 10.2.1, но это может быть просто совпадением.

Стоит отметить, что я использую Alamofire (4.3.0), где подобная проблема уже должна была быть исправлено.

Крашлог:

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

Обновлять:

После добавления дополнительного журнала я обнаружил, что сбой происходит во время Фонового обновления приложения. Согласно документации, "приложение имеет до 30 секунд стены -часы времени для выполнения операции загрузки и вызова указанного блока обработчика завершения».

Однако в журналах я вижу, что сбой происходит в то же время (в ту же секунду — я не вижу миллисекунды в журналах сбоев), когда выполняется запрос. Другими словами, между системными вызовами func application(_ application:, performFetchWithCompletionHandler: и сбоем почти нет времени.

Следовательно, это не должно быть тем случаем, когда система убивает приложение из-за того, что оно проводит слишком много времени в фоновом режиме.


person Tom Kraina    schedule 05.04.2017    source источник


Ответы (1)


Это не имеет ничего общего с AlamoFire. Стек NSURLSession и NSURLConnection безумно сложен и в основном написан на C на основе CoreFoundation, что означает, что они также не получают преимуществ ARC. Скорее всего, это тонкая ошибка многопоточности где-то глубоко в стеке, которая возникает только при определенных обстоятельствах и, вероятно, сильно зависит от времени.

В данном конкретном случае объект был обнулен (вероятно, где-то из-за обнуления слабой ссылки), и какая-то часть стека CF все еще использует его и пытается разыменовать объект, чтобы сохранить его с помощью API-интерфейсов уровня C, что приводит к Разыменование нулевого указателя.

В частности, вы, вероятно, видите этот сбой: https://github.com/PhilipsHue/PhilipsHueSDK-iOS-OSX/issues/52

А вот избежать его у вас вряд ли получится. Лучше всего убедиться, что ваше приложение правильно сохраняет состояние и как можно быстрее перезапускается после холодного запуска, чтобы разница между холодным и теплым запуском не имела значения.

Тем не менее, одна вещь, которую вы можете попробовать, — это отменить все незавершенные соединения переднего плана, как только вы получите уведомление о переходе в фоновый режим, а затем перезапустить их в сеансе с discretionary, установленным в YES.

person dgatwood    schedule 26.04.2017