2012-07-20 10 views
7

Tengo un problema técnico bastante complicado y espero que haya algunos expertos en Webkit. Estoy trabajando en una aplicación de iOS para un cliente. La mayor parte de la aplicación es contenido HTML5 servido en los controladores UIWebView.Leyendo el rastro de la pila de fallas iOS Webkit

Hace aproximadamente una semana, el equipo de control de calidad comenzó a informar que la aplicación se bloquea. Hemos recibido aproximadamente 1 informe de fallas por día durante la última semana. Desafortunadamente, son el tipo de bloqueo en el que no se puede determinar un conjunto claro de pasos que reproduzcan consistentemente el bloqueo. Extrañamente, algunos de esos informes de fallos han estado usando versiones antiguas de la base de código de iOS, un código que se ejecuta con éxito durante meses sin que nadie note este comportamiento de bloqueo.

Pero lo que todas las situaciones de bloqueo tienen en común es que todas se ejecutan en un servidor actualizado que sirve la última versión de las páginas de la aplicación web HTML. Así que es bonito, parece que hemos hecho algo nuevo en el lado del servidor que está provocando que algo en el código de iOS se bloquee.

Los registros de fallos han sido bastante consistentes. Aquí está el registro de symbolicated: (. La mayoría de las preguntas que tratan sobre accidentes en el WebCore son respondidas con una sugerencia de que se establece la webview.delegate a cero en el método dealloc Eso no parece ser nuestro 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 

.

Ahora tengo una teoría (de la que hablaré en un momento), pero lo que no tengo es una evidencia clara. Así que agarré la fuente de webkit.org y estoy tratando de leer lo suficiente para entender qué estaba haciendo WebKit en el momento en que se colgó. No creo que esté usando la misma versión de la fuente WebKit que en los dispositivos iOS (lo hemos visto en los dispositivos 5.0.1 y 5.1.1), parece que los métodos clave parecen referenciar los recursos de descarga (como CSS e imágenes) pero parece que hay una URL nula involucrada, así que terminamos llamando al método cancelledError.

El FrameLoader continuación, hace esto:

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

y es en este método que la aplicación se bloquea con:

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

la que me hace pensar que la m_client no está apuntando a algo válido.

Ahora, tengo una teoría sobre lo que está sucediendo, solo basada en la intuición y la evidencia circunstancial.

Nuestro UIWebView tiene un delegado que evalúa las URL que se cargan en la vista web. En ciertas circunstancias, decidimos poner en marcha nuevas direcciones URL en un ViewController separada, así:

- (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 de las condiciones principales que causa esta estrategia emergente para volver verdadera ocurre durante un enlace entre dominios. Es decir, si el usuario toca un enlace/icono y el objetivo de ese enlace está alojado en un sitio de un tercero, la aplicación lanza el nuevo contenido en un ViewController diferente (por diversas razones, incluida la posibilidad de obtener un buena transición nativa en enlaces entre dominios).

Uno de los cambios en el lado del servidor que sucedió hace unas semanas es que el enlace href se ha actualizado; el enlace ahora llama a nuestro servidor principal, que envía una redirección HTTP que envía al cliente al sitio de terceros .

Lo que veo en este caso es que nuestra popupStrategy recibe dos llamadas.La primera vez, está evaluando la URL de nuestro servidor principal, y la segunda vez, evalúa la URL de terceros. En el segundo caso, la estrategia le dice a UIWebView que cargue la solicitud en un nuevo ViewController. Mi pensamiento es que algo en el código de Webkit no siempre le gusta, y debido a algunas rarezas de tiempo o lo que sea, esto de alguna manera lleva a un colapso en algún momento.

Esta teoría me sigue porque está basada en un nuevo comportamiento de carga web que no existía anteriormente en nuestra base de código de servidor, que se ajusta convenientemente a los síntomas. Mi lectura del código de Webkit es que, en algunos de los métodos a los que se hace referencia, Webkit parece estar haciendo un procesamiento especial cuando ve solicitudes de origen cruzado. Pero el accidente ha sido imposible de reproducir en el momento justo, por lo que no tenemos mucho más para seguir. Pero si la teoría es cierta, sé una solución razonable.

Mi esperanza es que alguien tiene cierta familiaridad con las partes internas de WebKit y pueden sugerir:

a) lo bien que esta teoría es apoyada por el Webkit pila-trace?

b) ¿hay alguna otra información que cualquiera pueda ver sugerida por el seguimiento de la pila que obtengo?

Respuesta

0

Terminé haciendo cambios de código, enraizados en la teoría que describí anteriormente. Después de realizar esos cambios, no vi una repetición del bloqueo. Entonces la teoría original parece haber sido correcta.

+0

¿Qué hiciste para solucionar este problema? Estamos experimentando exactamente lo mismo ahora. – Shoerob

+0

Me aseguré de que la transición al nuevo controlador ocurriera * antes * de que se encontrara una redirección. – bcholmes

Cuestiones relacionadas