2012-07-20 10 views
7

Mam dość gnarly problem techniczny i mam nadzieję, że może być trochę ekspertów Webkit wokół. Pracuję nad aplikacją na iOS dla klienta. Większość aplikacji to treści HTML5 wyświetlane w kontrolerach UIWebView.Czytanie śladu po awarii zestawu narzędziowego iOS Webkit

Około tygodnia temu zespół ds. Kontroli jakości zaczął zgłaszać awarię aplikacji. Codziennie otrzymywaliśmy 1 raport o awarii z ostatniego tygodnia. Niestety, są to awarie, w których nie można ustalić wyraźnego zestawu kroków, które konsekwentnie odtwarzają awarię. Co dziwne, niektóre z tych raportów o awariach używały starych wersji kodu na iOS - kodu, który działa z powodzeniem od miesięcy, i nikt nie zauważył tego zachowania awaryjnego.

Jednak wszystkie sytuacje awaryjne mają wspólną cechę, że wszystkie działają na uaktualnionym zapleczu obsługującym najnowszą wersję stron aplikacji HTML. Wygląda to całkiem nieźle - wydaje się, że zrobiliśmy coś nowego po stronie serwera, które uruchamia coś w kodzie iOS.

Dzienniki awarii są dość spójne. Oto symbolicated log: (. Większość pytań, które omawiają wypadki w WebCore są odbierane z sugestią, że ustawia się webview.delegate do zera w metodzie dealloc To nie wydaje się być nasz problem)

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 

.

Teraz mam jedną teorię (o której za chwilę będę mówić), ale to, czego nie mam, to oczywisty dowód. Więc złapałem źródło z webkit.org i próbuję przeczytać wystarczająco dużo, aby zrozumieć, co robił WebKit w momencie, kiedy się rozbił. Nie sądzę, że używam tej samej wersji źródła WebKit, co na urządzeniach z iOS (widzieliśmy to na urządzeniach 5.0.1 i 5.1.1), wydaje się, że kluczowe metody odnoszą się do zasobów pobierania (takich jak CSS i obrazy), ale wydaje się, że ma on zerowy adres URL, więc na koniec wywołujemy metodę cancelledError.

Następnie FrameLoader robi to:

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

i to w ten sposób, że awarie app z:

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

co sugeruje mi, że m_client nie wskazuje na coś ważnego.

Mam teraz teorię na temat tego, co się dzieje, oparte na odczuciach jelitowych i poszlakach.

Nasz UIWebView ma delegata, który ocenia adresy URL ładowane do widoku internetowego. W pewnych okolicznościach, zdecydujemy się uruchomić nowe adresy URL w oddzielnym ViewController, tak:

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

    } 
    ... 
} 

Jednym z kluczowych warunków, które powoduje tę strategię podręczne powrotu prawda występuje podczas linkiem cross-domain. Oznacza to, że jeśli użytkownik kliknie na link/ikonę, a cel tego linku jest hostowany przez stronę trzecią, aplikacja uruchamia nową zawartość w innym ViewController (z różnych powodów, w tym możliwość uzyskania dobra natywna zmiana na linkach międzydomenowych).

Jedna ze zmian wprowadzonych po stronie serwera kilka tygodni temu jest to, że link href został zaktualizowany - link teraz wywołuje nasz główny serwer, który odsyła przekierowanie HTTP wysyłając klienta do strony trzeciej. .

W tym przypadku widzę, że nasza popupStrategy jest wywoływana dwa razy.Za pierwszym razem oceniamy adres URL naszego serwera głównego i po raz drugi oceniamy URL strony trzeciej. W drugim przypadku strategia informuje UIWebView, aby załadował żądanie w nowym kontrolerze ViewController. Uważam, że coś w kodzie Webkita nie zawsze się to podoba, a dzięki pewnym osobliwościom czasu lub czegokolwiek, to w pewnym sensie prowadzi do awarii.

Teoria ta wiąże się ze mną, ponieważ opiera się na nowym sposobie ładowania stron internetowych, które wcześniej nie istniało w naszej bazie kodu serwera, co wygodnie pasuje do objawów. Moje odczytywanie kodu Webkit polega na tym, że w niektórych z wymienionych metod Webkit wydaje się robić specjalne przetwarzanie, gdy widzi żądania krzyżowe. Ale zderzenie było niemożliwe do odtworzenia na podstawie wskazówek, więc nie mamy o wiele więcej do zrobienia. Ale jeśli teoria jest prawdziwa, znam rozsądną poprawkę.

Mam nadzieję, że ktoś ma jakieś znajomości wewnętrznych WebKit i może sugerować:

a), jak również ta teoria jest obsługiwany przez Webkit stosu śladu?

b) czy są jakieś inne spostrzeżenia, które ktoś może zobaczyć, sugerowane przez ślad stosu, który dostaję?

Odpowiedz

0

Skończyło się na wprowadzeniu zmian kodu, zakorzenionych w teorii, którą opisałem powyżej. Po wprowadzeniu zmian nie widziałem powtórki awarii. Tak więc pierwotna teoria wygląda na poprawną.

+0

Co zrobiłeś, aby rozwiązać ten problem? W tej chwili doświadczamy dokładnie tego samego. – Shoerob

+0

Upewniłem się, że przejście do nowego kontrolera nastąpiło * przed * napotkaniem przekierowania. – bcholmes

Powiązane problemy