【发布时间】:2017-05-18 20:15:19
【问题描述】:
我有一个 iOS 应用程序似乎随机在具有 UIWebView 的屏幕上崩溃。看起来崩溃主要发生在 iPhone 5C 设备上(74% 的时间)和 100% 的时间在 iOS 10.X 上。
异常信息是:
EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000028
从那个低内存地址让我觉得是nil。
这是回溯(这不是主线程):
0 WebCore WebCore::FrameTree::top() + 0
1 WebCore WebCore::ContentSecurityPolicy::allowFrameAncestors() + 33
2 WebCore WebCore::DocumentLoader::responseReceived() + 413
3 WebCore WebCore::DocumentLoader::handleSubstituteDataLoadNow() + 203
4 WebCore WebCore::ThreadTimers::sharedTimerFiredInternal() + 149
5 WebCore WebCore::timerFired() + 23
6 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 15
7 CoreFoundation __CFRunLoopDoTimer + 833
8 CoreFoundation __CFRunLoopDoTimers + 189
9 CoreFoundation __CFRunLoopRun + 781
10 CoreFoundation CFRunLoopRunSpecific + 471
11 CoreFoundation CFRunLoopRunInMode + 105
12 WebCore RunWebThread() + 427
13 libsystem_pthread.dylib _pthread_body + 217
14 libsystem_pthread.dylib _pthread_start + 235
我自己无法重现此崩溃。
由于 WebKit 是开源的,我找到了它崩溃的代码:WebCore::FrameTree::top。通过查看该代码,我猜m_thisFrame->tree() 是NULL,但我不知道如何解释它。我不确定在这种情况下“框架”和“树”到底是什么。
从回溯来看,似乎有一些计时器被触发了,可能是在 View Controller 或 Web View 已经被释放之后?该计时器是由 JavaScript setTimeout 调用引起的吗?
我还注意到,每次发生这种崩溃时,我都会在崩溃前接到[UIWebViewDelegate webView:didFailLoadWithError:] 的电话。该委托方法中返回的最常见错误是:
- 帧加载中断
- HTTP 重定向过多
- 请求超时
但我没有适当的分析来将错误消息与崩溃关联起来,所以我不确定哪个(如果有的话)可以解释它。当该委托方法触发时,我会在模式中向用户显示一条错误消息。这可能与坠机有关吗?我尝试重现“帧加载中断”和“HTTP 重定向过多”错误,但在模拟器中都没有导致我崩溃。
我已经遵循this answer 中的建议(大部分)并在viewWillDisappear 中调用[webview stopLoading],我在包含视图控制器的dealloc 中调用self.webView.delegate = nil,但它没有帮助。
【问题讨论】:
-
我面临同样的问题。你找到解决办法了吗?
-
我不会把这个作为答案,因为它是推测,但我认为切换到 WKWebView 可能会解决这些类型的崩溃。
-
谢谢。我会试试的。
-
由于家长控制设置和 MDM 黑名单,我看到了同样的崩溃它在切换到 WKWebView 后不再发生。