2011-12-22 26 views
6

Tengo una aplicación basada en HTML5 que se ejecuta en iOS y quiero conectarme a ella utilizando el protocolo de depurador webkit 1 que ahora es compatible con iOS 5 2.¿Es posible conectarse al protocolo de depuración remota de Mobile Safari usando python?

Estoy intentando rastrear un problema donde mi aplicación javascript está bloqueando el navegador (SEG_FAULT). Me gustaría obtener un rastro de la aplicación a medida que se ejecuta, así puedo ver qué línea (s) u operaciones de red pueden estar causando el problema. Mi idea actual es escribir una aplicación de Python que se conectará al depurador remoto y seguirá avanzando por el código y recopilando información en un archivo de registro mientras interactúo con la aplicación.

Me encontré con un obstáculo inicial, aunque no puedo encontrar ningún ejemplo o documentación sobre cómo conectarme al depurador y comunicarme o incluso si es posible.

¿Alguien sabe si esto es posible y, en caso afirmativo, puede indicarme algún tipo de documentación y/o código de ejemplo?


Basado en el código de abajo también creé un proyecto en github para probar algunas de las ideas. Puede encontrarlo aquí: abierbaum:/python_webkit-remote_debugger

+0

He mirado en esto un poco más y suena como debería ser posible simplemente no puedo encuentre cualquier documentación que proporcione un buen punto de partida. Una vez que pueda encontrar un "conectarse a este puerto y hablar este protocolo", entonces creo que puedo tomarlo desde allí. – Allen

Respuesta

6

Sí, si tiene el inspector habilitado en su UIWebView siguiendo las instrucciones, debería ser posible conectarse desde Python. Jugué con eso y descubrí cómo enviar y recibir comandos usando un Socket Web. Aquí hay un script para Python 2.7 utilizando websocket-client

import json 
import socket 

from websocket import WebSocket 


ws = WebSocket() 

# if ipv6 
ws.io_sock = ws.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 
ws.connect("ws://localhost:9999/devtools/page/1") 

counter = 0 

def send(method, params): 
    global counter 
    counter += 1 
    # separators is important, you'll get "Message should be in JSON format." otherwise 
    message = json.dumps({"id": counter, "method": method, "params": params}, separators=(',', ':')) 
    print "> %s" % (message,) 
    ws.send(message) 

def recv(): 
    result = ws.recv() 
    print "< %s" % (result,) 

send('Runtime.evaluate', {'expression': 'alert("hello from python")'}) 
recv() 

Esto utiliza la función Runtime.evaluate para mostrar una alerta.

Intenté ejecutarlo contra MobileSafari corriendo en el simulador, y funcionó bien. Noté dos cosas importantes:

  • el servidor remoto está vinculado a un puerto IPv6, y websocket-client no se conectó sin la línea para anular el socket y establecer la familia. No estoy seguro si sería lo mismo ejecutar en un dispositivo o en un UIWebView.
  • no le gustan los espacios alrededor de los separadores en el JSON.

Esto es lo que parece que permite al inspector en MobileSafari usando GDB y ejecutar el script:

$ ps x | grep MobileSafari 
4968 ?? Z  0:00.00 (MobileSafari) 
6234 ?? S  0:00.69 /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk//Applications/MobileSafari.app/MobileSafari 
6238 s007 R+  0:00.00 grep MobileSafari 
$ gdb 
GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Thu Nov 3 21:59:02 UTC 2011) 
... 
(gdb) attach 6234 
Attaching to process 6234. 
Reading symbols for shared libraries . done 
Reading symbols for shared libraries ........................................................................................................................................................ done 
0x99798c22 in mach_msg_trap() 
(gdb) p (void *)[WebView _enableRemoteInspector] 
$1 = (void *) 0x2ac93ce 
(gdb) detach 
Detaching from process 6234. 
(gdb) quit 
$ python debug.py 
> {"params":{"expression":"alert(\"hello from python\")"},"id":1,"method":"Runtime.evaluate"} 
< {"result":{"result":{"type":"undefined","description":"undefined"}},"id":1} 
+0

Impresionante. Has hecho algo con las notificaciones que vienen desde el lado remoto. (por ejemplo, ver una lista en vivo de las notificaciones de Network.requestWillBeSent para que pueda ver lo que está a punto de solicitar el navegador) – Allen

Cuestiones relacionadas