2017-09-30 291 views
2

我正在調試我們的應用程序的用戶報告,在iOS11的背景下重複退出,即使在主動使用期間(例如,用戶背景我們並返回一些幾秒或一分鐘,只能發現它重新啓動)。崩潰日誌都顯示相同的原因:看門狗超時。下面是一個這樣的崩潰日誌的相關位:iOS11看門狗超時崩潰(0x8badf00d)但代碼不在堆棧

Exception Type: EXC_CRASH (SIGKILL) 
Exception Codes: 0x0000000000000000, 0x0000000000000000 
Exception Note: EXC_CORPSE_NOTIFY 
Termination Reason: Namespace <0xF>, Code 0x8badf00d 
Triggered by Thread: 0 

我認識到,我們的代碼具有的接收推送通知或轉到後臺運行時,在此期間操作時有限的一段時間。我們絕對不使用UIBackgroundTasks(與Alamofire Networking,FWIW),我們也有到期處理程序做到這一點:

backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{ 
    [application endBackgroundTask:backgroundTask]; 
    backgroundTask = UIBackgroundTaskInvalid; // Set the task to be invalid 
    DebugLog(@"Ended because expiration"); 
}]; 

這些崩潰報告中最令人困惑的事情是,我們的代碼是無處上的堆棧。我們從this Apple discussion of the 0x8badf00d exception code可以看到,實際上,在主線程上主動執行有問題的代碼。

但是,在我的情況下,沒有任何堆棧有任何我的代碼正在執行。下面是一個代表性的樣本:

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libsystem_kernel.dylib   0x0000000183208bc4 0x183208000 + 3012 
1 libsystem_kernel.dylib   0x0000000183208a3c 0x183208000 + 2620 
2 CoreFoundation     0x00000001836b9c4c 0x1835d0000 + 957516 
3 CoreFoundation     0x00000001836b7818 0x1835d0000 + 948248 
4 CoreFoundation     0x00000001835d7e78 0x1835d0000 + 32376 
5 GraphicsServices    0x000000018546cf84 0x185462000 + 44932 
6 UIKit       0x000000018d37a0bc 0x18d307000 + 471228 
7 MyApp       0x0000000102a6572c main + 87852 (main.m:22) 
8 libdyld.dylib     0x00000001830fa56c 0x1830f9000 + 5484 

Thread 1 name: com.apple.uikit.eventfetch-thread 
Thread 1: 
0 libsystem_kernel.dylib   0x0000000183208bc4 0x183208000 + 3012 
1 libsystem_kernel.dylib   0x0000000183208a3c 0x183208000 + 2620 
2 CoreFoundation     0x00000001836b9c4c 0x1835d0000 + 957516 
3 CoreFoundation     0x00000001836b7818 0x1835d0000 + 948248 
4 CoreFoundation     0x00000001835d7e78 0x1835d0000 + 32376 
5 Foundation      0x00000001840006e4 0x183ff4000 + 50916 
6 Foundation      0x000000018401fafc 0x183ff4000 + 178940 
7 UIKit       0x000000018ded9630 0x18d307000 + 12396080 
8 Foundation      0x0000000184101860 0x183ff4000 + 1103968 
9 libsystem_pthread.dylib   0x000000018333c31c 0x18333a000 + 8988 
10 libsystem_pthread.dylib   0x000000018333c1e8 0x18333a000 + 8680 
11 libsystem_pthread.dylib   0x000000018333ac28 0x18333a000 + 3112 

Thread 2 name: com.twitter.crashlytics.ios.MachExceptionServer 
Thread 2: 
0 libsystem_kernel.dylib   0x0000000183208bc4 0x183208000 + 3012 
1 libsystem_kernel.dylib   0x0000000183208a3c 0x183208000 + 2620 
2 MyApp       0x0000000102cdaad8 CLSMachExceptionServer + 100 
3 libsystem_pthread.dylib   0x000000018333c31c 0x18333a000 + 8988 
4 libsystem_pthread.dylib   0x000000018333c1e8 0x18333a000 + 8680 
5 libsystem_pthread.dylib   0x000000018333ac28 0x18333a000 + 3112 

Thread 3 name: com.apple.NSURLConnectionLoader 
Thread 3: 
0 libsystem_kernel.dylib   0x0000000183208bc4 0x183208000 + 3012 
1 libsystem_kernel.dylib   0x0000000183208a3c 0x183208000 + 2620 
2 CoreFoundation     0x00000001836b9c4c 0x1835d0000 + 957516 
3 CoreFoundation     0x00000001836b7818 0x1835d0000 + 948248 
4 CoreFoundation     0x00000001835d7e78 0x1835d0000 + 32376 
5 CFNetwork      0x0000000183d41de0 0x183c93000 + 716256 
6 Foundation      0x0000000184101860 0x183ff4000 + 1103968 
7 libsystem_pthread.dylib   0x000000018333c31c 0x18333a000 + 8988 
8 libsystem_pthread.dylib   0x000000018333c1e8 0x18333a000 + 8680 
9 libsystem_pthread.dylib   0x000000018333ac28 0x18333a000 + 3112 

Thread 4 name: AVAudioSession Notify Thread 
Thread 4: 
0 libsystem_kernel.dylib   0x0000000183208bc4 0x183208000 + 3012 
1 libsystem_kernel.dylib   0x0000000183208a3c 0x183208000 + 2620 
2 CoreFoundation     0x00000001836b9c4c 0x1835d0000 + 957516 
3 CoreFoundation     0x00000001836b7818 0x1835d0000 + 948248 
4 CoreFoundation     0x00000001835d7e78 0x1835d0000 + 32376 
5 AVFAudio      0x0000000189615774 0x189591000 + 542580 
6 AVFAudio      0x0000000189640018 0x189591000 + 716824 
7 libsystem_pthread.dylib   0x000000018333c31c 0x18333a000 + 8988 
8 libsystem_pthread.dylib   0x000000018333c1e8 0x18333a000 + 8680 
9 libsystem_pthread.dylib   0x000000018333ac28 0x18333a000 + 3112 

Thread 5: 
0 libsystem_kernel.dylib   0x0000000183229150 0x183208000 + 135504 
1 libsystem_pthread.dylib   0x000000018333ed30 0x18333a000 + 19760 
2 libc++.1.dylib     0x00000001828e3ea4 0x1828dc000 + 32420 
3 JavaScriptCore     0x000000018b157d00 0x18a812000 + 9723136 
4 JavaScriptCore     0x000000018b157c28 0x18a812000 + 9722920 
5 JavaScriptCore     0x000000018b157f8c 0x18a812000 + 9723788 
6 libsystem_pthread.dylib   0x000000018333c31c 0x18333a000 + 8988 
7 libsystem_pthread.dylib   0x000000018333c1e8 0x18333a000 + 8680 
8 libsystem_pthread.dylib   0x000000018333ac28 0x18333a000 + 3112 

Thread 6 name: WebThread 
Thread 6: 
0 libsystem_kernel.dylib   0x0000000183208bc4 0x183208000 + 3012 
1 libsystem_kernel.dylib   0x0000000183208a3c 0x183208000 + 2620 
2 CoreFoundation     0x00000001836b9c4c 0x1835d0000 + 957516 
3 CoreFoundation     0x00000001836b7818 0x1835d0000 + 948248 
4 CoreFoundation     0x00000001835d7e78 0x1835d0000 + 32376 
5 WebCore       0x000000018bc1c75c 0x18bbdb000 + 268124 
6 libsystem_pthread.dylib   0x000000018333c31c 0x18333a000 + 8988 
7 libsystem_pthread.dylib   0x000000018333c1e8 0x18333a000 + 8680 
8 libsystem_pthread.dylib   0x000000018333ac28 0x18333a000 + 3112 

Thread 7 name: WebCore: LocalStorage 
Thread 7: 
0 libsystem_kernel.dylib   0x0000000183229150 0x183208000 + 135504 
1 libsystem_pthread.dylib   0x000000018333ed30 0x18333a000 + 19760 
2 JavaScriptCore     0x000000018a81fa18 0x18a812000 + 55832 
3 JavaScriptCore     0x000000018b13da04 0x18a812000 + 9615876 
4 WebKitLegacy     0x000000018d00f5fc 0x18cf7c000 + 603644 
5 WebKitLegacy     0x000000018d01226c 0x18cf7c000 + 615020 
6 WebKitLegacy     0x000000018d011998 0x18cf7c000 + 612760 
7 JavaScriptCore     0x000000018a81c010 0x18a812000 + 40976 
8 JavaScriptCore     0x000000018a81bf50 0x18a812000 + 40784 
9 libsystem_pthread.dylib   0x000000018333c31c 0x18333a000 + 8988 
10 libsystem_pthread.dylib   0x000000018333c1e8 0x18333a000 + 8680 
11 libsystem_pthread.dylib   0x000000018333ac28 0x18333a000 + 3112 

Thread 8 name: com.apple.CFSocket.private 
Thread 8: 
0 libsystem_kernel.dylib   0x0000000183229570 0x183208000 + 136560 
1 CoreFoundation     0x00000001836c2184 0x1835d0000 + 991620 
2 libsystem_pthread.dylib   0x000000018333c31c 0x18333a000 + 8988 
3 libsystem_pthread.dylib   0x000000018333c1e8 0x18333a000 + 8680 
4 libsystem_pthread.dylib   0x000000018333ac28 0x18333a000 + 3112 

Thread 9: 
0 libsystem_pthread.dylib   0x000000018333ac1c 0x18333a000 + 3100 

Thread 10: 
0 libsystem_kernel.dylib   0x0000000183229dbc 0x183208000 + 138684 
1 libsystem_pthread.dylib   0x000000018333afa0 0x18333a000 + 4000 
2 libsystem_pthread.dylib   0x000000018333ac20 0x18333a000 + 3104 

Thread 11: 
0 libsystem_pthread.dylib   0x000000018333ac1c 0x18333a000 + 3100 

Thread 0 crashed with ARM Thread State (64-bit): 
    x0: 0x0000000010004005 x1: 0x0000000007000806 x2: 0x0000000000000000 x3: 0x0000000000000c00 
    x4: 0x0000000000002b03 x5: 0x00000000ffffffff x6: 0x0000000000000000 x7: 0x0000000000000000 
    x8: 0x00000000fffffbbf x9: 0x0000000007000000 x10: 0x0000000007000100 x11: 0x0000000000000040 
    x12: 0xffffffffffffffff x13: 0x0000000000000001 x14: 0x01e8540001e85400 x15: 0x0000000000000000 
    x16: 0xffffffffffffffe1 x17: 0x00000000ffffffff x18: 0x0000000000000000 x19: 0x0000000000000000 
    x20: 0x00000000ffffffff x21: 0x0000000000002b03 x22: 0x0000000000000c00 x23: 0x000000016d3aed38 
    x24: 0x0000000007000806 x25: 0x0000000000000000 x26: 0x0000000007000806 x27: 0x0000000000000c00 
    x28: 0x0000000000000001 fp: 0x000000016d3aec30 lr: 0x0000000183208a3c 
    sp: 0x000000016d3aebe0 pc: 0x0000000183208bc4 cpsr: 0x60000000 

的運行我的代碼只有一部分是main.m文件,22行,這是

int retVal = UIApplicationMain(argc, argv, nil, @"PSSMyAppDelegate"); 

因此,我很困惑,我的應用程序怎麼可能因爲看起來我的代碼實際上並沒有運行,所以會因爲運行時間違規而反覆殺死。 iOS 11中是否有新內容可以改變看門狗進程的行爲?如果沒有,我怎麼知道我的代碼的哪一部分是違反運行時間過長的部分?

回答

1

我在蘋果誰介紹的問題如下工程師發言didReceiveRemoteNotification):

[self startTask]; 
[self startTask]; 

據我們採訪的工程師,應用程序會崩潰,那麼正是我們所看到的方式。

而且,從技術上講,我們的應用程序會崩潰,我們創建結束第一個任務之前,第二個任務的任何時間。除非後臺任務直接連接到直接管理其生命週期並且不能「擁有」多於一個的其他對象(例如,獨立操作在創建時開始1個任務,並在完成/銷燬時結束),這是非常難以避免「任務重入」問題。

更好的選擇是依靠任務期滿的局部變量,保持你的對象的成員變量進行到期處理程序。

2

你的線程0看起來很像崩潰,我們在iOS的11遇到這是我們的:

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libsystem_kernel.dylib   0x00000001853c4bc4 mach_msg_trap + 8 
1 libsystem_kernel.dylib   0x00000001853c4a3c mach_msg + 72 
2 CoreFoundation     0x0000000185875c4c __CFRunLoopServiceMachPort + 196 
3 CoreFoundation     0x0000000185873818 __CFRunLoopRun + 1424 
4 CoreFoundation     0x0000000185793e78 CFRunLoopRunSpecific + 436 
5 GraphicsServices    0x0000000187628f84 GSEventRunModal + 100 
6 UIKit       0x000000018f5360bc UIApplicationMain + 208 
7 TestCrashInBackground   0x0000000100e8dbac 0x100e88000 + 23468 
8 libdyld.dylib     0x00000001852b656c start + 4 

對於我們的問題是,顯示通知導致應用程序崩潰(當應用程序在背景執行)。我們甚至創建了一個測試應用程序(您可以在上面看到的TestCrashInBackground)來重現此問題。該應用程序只顯示通知,並沒有任何後臺任務。 測試用例是:

  1. 該應用程序顯示的通知
  2. 用戶背景的應用程序(按壓主頁鍵)。
  3. 用戶鎖定屏幕

結果:OS後一些(短)的時間殺死該應用。

在發生這種情況後我們已經採用了sysdiagnose,我們可以看到,當我們顯示通知時,會添加名爲「將呈現通知」的斷言。

default 2017-10-03 14:32:16.280562 +0200 assertiond [SpringBoard:53] Attempting to acquire assertion for TestCrashInBack:507: <BKProcessAssertion: 0x1c90; "will present notification" (notificationAction:30s); id:…E1D79D51D1D9> 
default 2017-10-03 14:32:16.281283 +0200 assertiond [TestCrashInBack:507] Add assertion: <BKProcessAssertion: 0x1c90; id: 53-96A5F4EA-4C42-4675-97E4-E1D79D51D1D9; name: "will present notification"; state: active; reason: notificationAction; duration: 30.0s> { 
    owner = <BSProcessHandle: 0x10110a810; SpringBoard:53; valid: YES>; 
    flags = preventSuspend, preventThrottleDownUI, preventIdleSleep, preventSuspendOnSleep; 
} 

約45秒的應用程序被終止,因爲它「已經超出允許的時間積極斷言」後:

default 2017-10-03 14:33:00.436085 +0200 assertiond [TestCrashInBack:507] Forcing crash report with description: TestCrashInBack:507 has active assertions beyond permitted time: 
<BKProcessAssertion: 0x1c90; "will present notification" (notificationAction:30s); id:…E1D79D51D1D9> (owner: SpringBoard:53) 

這一切只是用於顯示通知...相當嚴重的錯誤!

這是增加了該通知的代碼:我們的測試項目,並附着在sysdiagnose:

UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; 
content.body = NSLocalizedString(@"This is test notification", nil); 

UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:content.body content:content trigger:[UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1.0 repeats:NO]]; 
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { 
    NSLog(@"display notification error:%@", error); 
}]; 

我已經提交了一份bug報告給蘋果(34788843號)。希望他們很快就能解決這個問題。

- (void)startTask { 
    self.bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ 
     [application endBackgroundTask:self.bgTask]; 
     self.bgTask = UIBackgroundTaskInvalid; 
    }]; 
} 

的代碼然後調用它兩次(比方說,因爲我們收到兩個電話給: 想像我們有這樣的方法 -