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ę?
Co zrobiłeś, aby rozwiązać ten problem? W tej chwili doświadczamy dokładnie tego samego. – Shoerob
Upewniłem się, że przejście do nowego kontrolera nastąpiło * przed * napotkaniem przekierowania. – bcholmes