iOS11 看门狗超时崩溃(0x8badf00d)但代码不在堆栈上
Posted
技术标签:
【中文标题】iOS11 看门狗超时崩溃(0x8badf00d)但代码不在堆栈上【英文标题】:iOS11 watchdog timeout crashes (0x8badf00d) but code not on stack 【发布时间】:2017-09-30 00:58:25 【问题描述】:我正在调试用户报告我们的应用程序在 ios11 开始时在后台反复退出,即使在活跃使用期间也是如此(例如,用户将我们设置为后台并在几秒钟或一分钟内返回,却发现它重新启动)。崩溃日志都揭示了相同的原因:看门狗超时。以下是此类崩溃日志中的相关信息:
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】:您的线程 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),我们可以在其中重现此问题。该应用程序仅显示通知,没有任何后台任务。 测试用例是:
-
应用显示通知
用户将应用程序置于后台(按主页键)。
用户锁定屏幕
结果:操作系统会在一段时间(短)时间后终止应用。
我们在发生这种情况后进行了系统诊断,我们可以看到,当我们显示通知时,添加了一个名为“将呈现通知”的断言。
default 2017-10-03 14:32:16.280562 +0200 assertiond [SpringBoard:53] Attempting to acquire assertion for TestCrashInBack:507: <BKProcessAssertion: 0x101235c90; "will present notification" (notificationAction:30s); id:…E1D79D51D1D9>
default 2017-10-03 14:32:16.281283 +0200 assertiond [TestCrashInBack:507] Add assertion: <BKProcessAssertion: 0x101235c90; 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: 0x101235c90; "will present notification" (notificationAction:30s); id:…E1D79D51D1D9> (owner: SpringBoard:53)
所有这些只是为了显示一个通知...相当严重的错误!
这是添加通知的代码:
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);
];
我已向 Apple (id: 34788843) 提交了一份错误报告,并附上了我们的测试项目和 sysdiagnose。希望他们能尽快解决这个问题。
【讨论】:
【参考方案2】:我与 Apple 的一位工程师交谈过,他将问题描述如下—— 想象一下我们有这样的方法:
- (void)startTask
self.bgTask = [application beginBackgroundTaskWithExpirationHandler:^
[application endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
];
然后代码会调用它两次(比如说,因为我们收到了两次对 didReceiveRemoteNotification
的调用):
[self startTask];
[self startTask];
根据我们采访的工程师的说法,该应用程序随后将完全按照我们所看到的方式崩溃。
此外,从技术上讲,只要我们在结束第一个任务之前创建第二个任务,我们的应用就会崩溃。除非后台任务直接附加到其他直接管理其生命周期并且无法“拥有”多个任务的对象(例如,在创建时开始 1 个单个任务并在完成/销毁时结束它的独立操作),否则它非常难以避免“任务重入”的问题。
更好的选择是在任务到期时依赖局部变量,将您的对象成员变量排除在到期处理程序之外。
【讨论】:
以上是关于iOS11 看门狗超时崩溃(0x8badf00d)但代码不在堆栈上的主要内容,如果未能解决你的问题,请参考以下文章
iOS 应用程序因终止原因而崩溃:命名空间 SPRINGBOARD,代码 0x8badf00d
我在 iPhone 应用程序中收到错误 0x8badf00d,这不是通常的嫌疑人