2012-07-20 22 views
7

Tôi gặp vấn đề kỹ thuật khá gnarly và tôi hy vọng rằng có thể có một số chuyên gia về Webkit xung quanh. Tôi đang làm việc trên ứng dụng iOS cho khách hàng. Hầu hết ứng dụng là nội dung HTML5 được phân phối trong bộ điều khiển UIWebView.Đọc theo dõi ngăn xếp sự cố iOS Webkit

Khoảng một tuần trước, nhóm QA đã bắt đầu báo cáo rằng ứng dụng gặp sự cố. Chúng tôi đã nhận được khoảng 1 báo cáo sự cố mỗi ngày trong tuần qua. Thật không may, họ là loại tai nạn mà không có bộ rõ ràng các bước có thể được xác định rằng luôn tái tạo vụ tai nạn. Kỳ lạ thay, một số báo cáo sự cố đã sử dụng các phiên bản cũ của mã cơ sở iOS - mã được chạy thành công trong nhiều tháng mà không có ai nhận thấy hành vi tai nạn này.

Nhưng tất cả các tình huống tai nạn có điểm chung là tất cả chúng đều chạy trên nền tảng cập nhật phục vụ lên phiên bản mới nhất của các trang ứng dụng web HTML. Vì vậy, có vẻ như chúng tôi đã thực hiện điều gì đó mới mẻ ở phía máy chủ đang kích hoạt nội dung nào đó trong mã iOS bị lỗi.

Nhật ký sự cố đã khá nhất quán. Dưới đây là các bản ghi symbolicated: (. Hầu hết các câu hỏi mà thảo luận về tai nạn trong WebCore được trả lời bằng một gợi ý mà bạn thiết lập các webview.delegate để nil trong phương thức dealloc Đó dường như không phải là vấn đề của chúng tôi)

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 

.

Bây giờ tôi có một lý thuyết (mà tôi sẽ nói về trong một thời điểm), nhưng những gì tôi không có bằng chứng rõ ràng. Vì vậy, tôi lấy nguồn từ webkit.org và tôi đang cố gắng đọc đủ để hiểu WebKit đang làm gì vào thời điểm nó bị hỏng. Tôi không nghĩ rằng tôi đang sử dụng cùng một phiên bản của nguồn WebKit như trong các thiết bị iOS (chúng tôi đã thấy điều này trong các thiết bị 5.0.1 và 5.1.1), các phương pháp chính dường như xuất hiện để tham khảo tài nguyên tải xuống (như CSS và hình ảnh) nhưng dường như có một URL rỗng liên quan, vì vậy chúng tôi sẽ gọi phương thức cancelledError.

Các FrameLoader sau đó thực hiện điều này:

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

và đó là trong phương pháp này mà treo ứng dụng với:

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

mà gợi ý với tôi rằng m_client không chỉ vào một cái gì đó có giá trị.

Bây giờ, tôi có một lý thuyết về những gì đang xảy ra, chỉ dựa trên cảm giác ruột và bằng chứng gián tiếp.

UIWebView của chúng tôi có một đại biểu đánh giá các URL đang được tải vào chế độ xem web. Trong một số trường hợp, chúng tôi quyết định để khởi động các URL mới trong một ViewController riêng biệt, như vậy:

- (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 ... 

    } 
    ... 
} 

Một trong những điều kiện quan trọng mà gây chiến lược popup này để trở về đúng xảy ra trong một liên kết cross-domain. Tức là, nếu người dùng chạm vào liên kết/biểu tượng và mục tiêu của liên kết đó được lưu trữ bởi trang web của bên thứ ba, ứng dụng sẽ khởi chạy nội dung mới trong ViewController khác (vì nhiều lý do khác nhau, bao gồm cả việc có thể nhận được chuyển đổi tự nhiên tốt đẹp trên các liên kết tên miền chéo).

Một trong những thay đổi phía máy chủ đã xảy ra cách đây vài tuần là liên kết href đã được cập nhật - liên kết hiện gọi máy chủ chính của chúng tôi, gửi lại chuyển hướng HTTP gửi khách hàng đến trang web của bên thứ ba .

Điều tôi thấy trong trường hợp này là popupStrategy của chúng tôi được gọi hai lần.Lần đầu tiên, nó đánh giá URL đến máy chủ chính của chúng tôi và lần thứ hai, nó đánh giá URL của bên thứ ba. Trong trường hợp thứ hai, chiến lược cho UIWebView tải yêu cầu trong một ViewController mới. Suy nghĩ của tôi là một cái gì đó trong mã Webkit không phải lúc nào cũng giống như vậy, và thông qua một số điều kỳ quặc về thời gian hoặc điều gì đó, điều này bằng cách nào đó dẫn đến một vụ tai nạn tại một số điểm.

Lý thuyết này gắn bó với tôi bởi vì nó dựa trên hành vi tải web mới mà trước đây chưa tồn tại trong cơ sở mã máy chủ của chúng tôi, thuận tiện cho các triệu chứng. Đọc của tôi về mã Webkit là, trong một số phương pháp được tham chiếu, Webkit dường như đang thực hiện một số xử lý đặc biệt khi nó thấy các yêu cầu có nguồn gốc chéo. Nhưng vụ tai nạn đã không thể tái tạo trên cue, vì vậy chúng tôi không có nhiều hơn để tiếp tục. Nhưng nếu lý thuyết là đúng, tôi biết một sửa chữa hợp lý.

Hy vọng của tôi là ai đó có một số quen thuộc với internals Webkit và có thể đề nghị:

a) tốt như thế nào lý thuyết này được hỗ trợ bởi Webkit chồng-trace?

b) có bất kỳ thông tin chi tiết nào khác mà bất kỳ ai có thể nhìn thấy được đề xuất theo dấu vết ngăn xếp tôi nhận được không?

Trả lời

0

Tôi đã thực hiện thay đổi mã, bắt nguồn từ lý thuyết tôi mô tả ở trên. Sau khi những thay đổi đó được thực hiện, tôi không thấy sự tái diễn của vụ tai nạn. Vì vậy, lý thuyết ban đầu có vẻ đúng.

+0

Bạn đã làm gì để khắc phục sự cố này? Chúng tôi đang trải qua cùng một điều chính xác ngay bây giờ. – Shoerob

+0

Tôi đảm bảo rằng quá trình chuyển đổi sang bộ điều khiển mới đã xảy ra * trước khi một chuyển hướng gặp phải. – bcholmes

Các vấn đề liên quan