2012-07-20 11 views
7

Ho un problema tecnico piuttosto complesso e spero che ci possano essere degli esperti di Webkit in giro. Sto lavorando su un'applicazione iOS per un client. La maggior parte dell'applicazione è il contenuto HTML5 pubblicato nei controller UIWebView.Lettura dello stack stack per iOS Webkit

Circa una settimana fa, il team addetto al controllo qualità ha iniziato a segnalare che l'applicazione si arresta in modo anomalo. Abbiamo ricevuto circa 1 rapporto di incidente al giorno per l'ultima settimana. Sfortunatamente, sono il tipo di incidente in cui non è possibile determinare una serie di passaggi che riproducano in modo coerente l'arresto. Stranamente, alcuni di questi rapporti sugli arresti anomali hanno utilizzato versioni precedenti della base di codice iOS: codice che viene eseguito correttamente per mesi senza che nessuno si accorga di questo comportamento anomalo.

Ma ciò che accomuna tutte le situazioni di arresto è che tutte corrono contro un back-end aggiornato che serve l'ultima versione delle pagine di app Web HTML. Quindi sembra che abbiamo fatto qualcosa di nuovo sul lato server che sta facendo scattare qualcosa nel codice iOS.

I registri degli arresti anomali sono stati piuttosto coerenti. Ecco il registro symbolicated: (. La maggior parte delle domande che discutere crash del WebCore si risponde con un suggerimento che si imposta la webview.delegate a zero nel metodo dealloc Questo non sembra essere il nostro problema)

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 

.

Ora ho una teoria (di cui parlerò tra un momento), ma quello che non ho è una prova evidente. Così ho preso la fonte da webkit.org e sto cercando di leggerne abbastanza per capire cosa stava facendo WebKit nel momento in cui si è bloccato. Non penso di utilizzare la stessa versione di WebKit source come nei dispositivi iOS (lo abbiamo visto nei dispositivi 5.0.1 e 5.1.1), sembra che i metodi chiave facciano riferimento a risorse di download (come CSS e immagini) ma sembra esserci un URL nullo, quindi finiamo per chiamare il metodo cancelledError.

Il FrameLoader allora fa questo:

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

ed è in questo metodo che l'applicazione si blocca con:

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

che mi fa pensare che il m_client non punta a qualcosa di valido.

Ora, ho una teoria su ciò che sta accadendo, basandomi solo su sentimento istintivo e prove circostanziali.

Il nostro UIWebView dispone di un delegato che valuta gli URL caricati nella vista Web. In alcune circostanze, decidiamo di lanciare nuovi URL in un ViewController separata, in questo modo:

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

    } 
    ... 
} 

Una delle condizioni chiave che provoca questa strategia popup per tornare vero si verifica durante un collegamento tra domini. Vale a dire, se l'utente tocca un link/icona e la destinazione di quel collegamento è ospitata da un sito di terze parti, l'app avvia il nuovo contenuto in un ViewController diverso (per vari motivi, inclusa la possibilità di ottenere un bella transizione nativa su collegamenti interdominio).

Una delle modifiche sul lato server avvenute poche settimane fa è che il collegamento href è stato aggiornato - il collegamento ora chiama il nostro server principale, che rimanda un reindirizzamento HTTP inviando il client al sito di terze parti .

Quello che vedo in questo caso è che la nostra pop-upStrategy viene chiamata due volte.La prima volta, sta valutando l'URL del nostro server principale e la seconda volta valuta l'URL di terze parti. Nel secondo caso, la strategia indica a UIWebView di caricare la richiesta in un nuovo ViewController. Il mio pensiero è che qualcosa nel codice Webkit non sia sempre così, e attraverso alcune stranezze di tempismo o quant'altro, questo in qualche modo porta ad un crash ad un certo punto.

Questa teoria mi segue perché si basa sul nuovo comportamento di caricamento del Web che non esisteva in precedenza nel nostro codice di base del server, che si adatta convenientemente ai sintomi. La mia lettura del codice Webkit è che, in alcuni dei metodi a cui si fa riferimento, Webkit sembra eseguire alcune elaborazioni speciali quando rileva richieste di origine incrociata. Ma il crash è stato impossibile da riprodurre al momento giusto, quindi non abbiamo molto altro da fare. Ma se la teoria è vera, conosco una soluzione ragionevole.

La mia speranza è che qualcuno ha una certa familiarità con interni da parte di WebKit e può suggerire:

a) quanto bene questa teoria è supportata dal Webkit stack trace?

b) ci sono altre informazioni che chiunque può vedere suggerite dalla traccia di stack che sto ottenendo?

risposta

0

Ho finito per apportare modifiche al codice, basandomi sulla teoria che ho descritto sopra. Dopo queste modifiche sono state apportate, non ho visto una ricaduta dello schianto. Quindi la teoria originale sembra essere stata corretta.

+0

Cosa hai fatto per risolvere questo problema? Stiamo vivendo esattamente la stessa cosa in questo momento. – Shoerob

+0

Mi sono assicurato che la transizione al nuovo controller avvenisse * prima che * venisse riscontrato un reindirizzamento. – bcholmes

Problemi correlati