我有一個非常粗糙的技術問題,我希望可能會有一些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)是否有任何其他的見解,任何人都可以看到,我得到的堆棧跟蹤提示?
你做了什麼來解決這個問題?我們現在正在經歷同樣的事情。 – Shoerob 2013-08-22 19:59:36
我確保在遇到重定向之前轉換到新控制器。 – bcholmes 2013-09-16 20:47:52