2012-07-20 4 views
7

기술적 인 문제가 꽤 있으며 웹킷 전문가가있을 것으로 기대됩니다. 나는 클라이언트를위한 iOS 응용 프로그램에서 일하고있다. 대부분의 응용 프로그램은 UIWebView 컨트롤러에서 제공되는 HTML5 콘텐츠입니다.iOS Webkit 크래시 스택 추적 읽기

약 일주일 전에 QA 팀이 응용 프로그램이 충돌 함을보고하기 시작했습니다. 우리는 지난 주 동안 하루에 약 1 개의 충돌보고를 받고 있습니다. 불행히도 충돌 사고를 지속적으로 재현 할 수있는 확실한 단계를 결정할 수없는 종류의 충돌입니다. 이상하게도, 충돌 보고서 중 일부는이 충돌 동작을 알지 못하는 사람들이 몇 개월 동안 성공적으로 실행 한 iOS 코드 기반 코드의 이전 버전을 사용하고 있습니다.

하지만 모든 충돌 상황은 공통적으로 HTML 웹 앱 페이지의 최신 버전을 제공하는 업데이트 된 백엔드에 대해 모두 실행되고 있다는 점에서 공통점이 있습니다. 그래서 우리는 서버 측에서 새로운 것을 시도해 보았습니다. iOS 코드에서 충돌을 유발하는 것이 있습니다.

크래시 로그의 일관성이 유지되었습니다. 여기에 symbolicated 로그입니다 : (. WebCore에서 충돌이 발생하면 할당 해제의 방법에서 전무로 webview.delegate을 설정 제안에 대답하는 논의 대부분의 질문 즉, 우리의 문제가 될 것 같지 않습니다)

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 및 이미지) null null URL이 포함 된 것으로 보입니다. 따라서 결국 canceledError 메소드가 호출됩니다.

FrameLoader 다음이 수행합니다

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

을하고이 방법에있어 그와 응용 프로그램의 충돌 :

m_client가 유효 뭔가 가리키는되지 않는다는 것을 나에게 제안
Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x00000008 

.

이제 저는 직감과 상황에 근거한 증거를 토대로 상황에 대한 이론을 가지고 있습니다.

우리 UIWebView에는 웹보기로로드되는 URL을 평가하는 대리인이 있습니다. 특정 상황에서, 우리는과 같이 별도의 ViewController에 새로운 URL을 시작하기로 결정 : true를 돌려이 팝업 전략을 유발하는 주요 조건의

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

    } 
    ... 
} 

하나는 크로스 도메인 링크시 발생합니다. 즉, 사용자가 링크/아이콘을 탭하고 해당 링크의 대상이 제 3 자 사이트에 의해 호스팅되는 경우 앱은 다른 ViewController에서 새 콘텐츠를 시작합니다 (다양한 이유로 인해 교차 도메인 링크에서 멋진 네이티브 전환).

몇 주 전에 발생한 서버 측 변경 사항 중 하나는 링크 href가 업데이트되었다는 것입니다. 링크가 이제 클라이언트를 타사 사이트로 보내는 HTTP 리다이렉트를 보내는 당사의 주 서버를 호출합니다 .

이 경우에 나타나는 것은 popupStrategy가 두 번 호출된다는 것입니다.처음으로 주 서버에 대한 URL을 평가하고 두 번째로 제 3 자 URL을 평가합니다. 두 번째 경우에 전략은 새 ViewController에서 요청을로드하도록 UIWebView에 지시합니다. 내 생각에 Webkit 코드의 일부가 항상 그런 것은 아니며 타이밍이나 기타 여러 가지 이상한 점을 통해 어떤 점에서는 충돌이 발생합니다. 가 이전에 편리 증상에 맞는 우리의 서버 코드베이스에 존재하지 않았던 새로운 웹 로딩 행동을 기반으로하기 때문에

이 이론은 나와 함께 스틱. Webkit 코드를 읽은 것은 참조 된 일부 메소드에서 Webkit이 교차 출처 요청을 볼 때 특별한 처리를 수행하는 것 같습니다. 그러나 충돌이 큐에서 재생산하는 것은 불가능했기 때문에 더 이상 진행할 필요가 없습니다. 그러나 이론이 사실이라면, 나는 적당한 해결책을 안다.

내 희망은 누군가가 웹킷의 내부에 어느 정도 익숙을 가지고 있으며, 제안 할 수 있다는 것입니다 :

a)이 이론은 웹킷 스택 추적에서 지원하는 방법을 잘?

b) 누군가가 스택 추적에서 제안하는 것을 볼 수있는 다른 통찰력이 있습니까?

답변

0

필자는 앞에서 설명한 이론에 기인 한 코드 변경 작업을 마무리했습니다. 그 변화가 일어난 후에, 나는 충돌의 재발을 보지 못했다. 그래서 원래의 이론은 옳은 것처럼 보입니다.

+0

이 문제를 해결하기 위해 무엇을 했습니까? 우리는 지금 똑같은 일을 경험하고 있습니다. – Shoerob

+0

새 컨트롤러로의 전환이 * 리디렉션이 발생하기 전에 발생했는지 확인했습니다. – bcholmes