2012-07-20 106 views
7

我有一个非常粗糙的技术问题,我希望可能会有一些Webkit专家。我正在为客户端开发iOS应用程序。大部分应用程序都是在UIWebView控制器中提供的HTML5内容。阅读iOS Webkit崩溃堆栈跟踪

大约一个星期前,QA团队开始报告应用程序崩溃。上周我们每天都会收到1份关于崩溃的报告。不幸的是,他们是那种崩溃,没有明确的步骤可以确定,不断重现崩溃。奇怪的是,其中一些崩溃报告一直在使用旧版本的iOS代码库 - 这些代码几个月都能成功运行,没有人注意到这种崩溃行为。

但所有崩溃情况的共同之处在于,它们都运行在提供最新版HTML Web应用程序页面的更新后端上。因此,看起来我们已经在服务器端做了一些新的事情,这些事情触发了iOS代码中的某些东西来崩溃。

崩溃日志一直非常一致。这里的symbolicated日志:(即讨论在WebCore的崩溃与您在webview.delegate设置在dealloc方法无建议回答大多数问题似乎没有成为我们的问题)

0 WebCore 0x33147ab0 WebCore::FrameLoader::cancelledError(WebCore::ResourceRequest const&) const + 4 
1 WebCore 0x33070fbe WebCore::ResourceLoader::init(WebCore::ResourceRequest const&) + 166 
2 WebCore 0x33070e66 WebCore::SubresourceLoader::startLoading() + 14 
3 WebCore 0x33070c4e WebCore::ResourceLoadScheduler::servePendingRequests(WebCore::ResourceLoadScheduler::HostInformation*, WebCore::ResourceLoadPriority) + 46 
4 WebCore 0x33076508 WebCore::ResourceLoadScheduler::servePendingRequests(WebCore::ResourceLoadPriority) + 36 
5 WebCore 0x32fd38c8 WebCore::ThreadTimers::sharedTimerFiredInternal() + 92 

现在我有一个理论(我将在一会儿讨论),但我没有的是明确的证据。因此,我从webkit.org抓取了源代码,并试图阅读足够的内容以了解WebKit在崩溃时正在做什么。我不认为我使用的是与iOS设备完全相同的WebKit源代码版本(我们在5.0.1和5.1.1设备中已经看到过这个版本),但似乎这些关键方法引用了下载资源(如CSS和图像),但似乎有一个空的URL,所以我们最终调用了cancelledError方法。

的FrameLoader然后做到这一点:

ResourceError FrameLoader::cancelledError(const ResourceRequest& request) const 
{ 
    ResourceError error = m_client->cancelledError(request); 
    error.setIsCancellation(true); 
    return error; 
} 

,它是在这个方法中,该应用程序崩溃与:

Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x00000008 

这表明对我来说,m_client没有的东西有效的指向。

现在,我基于直觉和间接证据确实了解发生了什么。

我们的UIWebView有一个委托,用于评估加载到Web视图中的URL。在某些情况下,我们决定在一个单独的ViewController推出新的URL,就像这样:一个跨域连接过程中出现

- (BOOL)webView:(UIWebView *)source shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{ 
    ... 

    if ([self.popupStrategy shouldPopupURL:[request URL] fromCurrent:[source.request URL]]) { 

     PopupTransitionViewController *popController = [self createPopupController:request]; 
     ... push it onto the navigation controller ... 

    } 
    ... 
} 

其中一个导致此弹出策略返回true的关键条件。也就是说,如果用户点击链接/图标并且该链接的目标由第三方站点托管,则应用程序将在不同的ViewController中启动新内容(出于各种原因,包括能够获得跨域链接的本地转换不错)。

几个星期前发生的服务器端更改之一是链接href已更新 - 链接现在调用我们的主服务器,该服务器发送一个HTTP重定向将客户端发送到第三方站点。

我在这种情况下看到的是我们的popupStrategy被调用两次。它第一次评估我们的主服务器的URL,第二次评估第三方URL。在第二种情况下,策略通知UIWebView在新的ViewController中加载请求。我的想法是,Webkit代码中的某些东西并不总是那样,并且通过某些奇怪的时机或某些事情,这在某种程度上会导致崩溃。

这个理论坚持我,因为它基于新的网络加载行为,以前没有存在于我们的服务器代码库中,它可以方便地符合症状。我读过的Webkit代码是,在所引用的一些方法中,Webkit在看到跨源请求时似乎正在做一些特殊的处理。但是这个崩溃已经不可能在线索上重现,所以我们没有更多要继续。但如果理论是真的,我知道一个合理的解决方法。

我希望有人有一些熟悉WebKit的内部并可以建议:

一)有多好这一理论由WebKit堆栈跟踪支持?

b)是否有任何其他的见解,任何人都可以看到,我得到的堆栈跟踪提示?

回答

0

我最终根据上面介绍的理论进行了代码更改。这些变化发生后,我没有看到事故再次发生。所以最初的理论看起来是正确的。

+0

你做了什么来解决这个问题?我们现在正在经历同样的事情。 – Shoerob 2013-08-22 19:59:36

+0

我确保在遇到重定向之前转换到新控制器。 – bcholmes 2013-09-16 20:47:52