Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to connect to Mobile Safari remote debugger protocol using python?

I have an HTML5-based application running on iOS and I want to connect to it using the webkit remote debugger protocol 1 that is now supported in iOS 5 2.

I am trying to track down a problem where my javascript application is hard crashing the browser (SEG_FAULT). I would like to get a trace of the application as it executes so I can see what line(s) or network operations may be leading to the issue. My current idea is to write a python application that will connect to the remote debugger and keep stepping through the code and collecting information to a log file while I interact with the application.

I ran into an initial hurdle though that I can't find any examples or documentation about how to connect to the debugger and communicate or even if it is possible.

Does anyone know if this is possible and if so can you point me at some documentation and/or example code?


Based on the code from also below I created a project on github to test out some of the ideas. You can find it here: abierbaum:/python_webkit-remote_debugger

like image 591
Allen Avatar asked Dec 22 '11 04:12

Allen


1 Answers

Yes, if you've got the inspector enabled in your UIWebView by following the instructions, it should be possible to connect to it from Python. I played around with it, and figured out how to send and receive commands using a Web Socket. Here's a script for Python 2.7 using 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()

This uses the Runtime.evaluate function to show an alert.

I tried running it against MobileSafari running in the simulator, and it worked fine. I noticed two important things:

  • the remote server is bound to an IPv6 port, and websocket-client didn't connect without the line to override the socket and set the family. Not sure if it would be the same running on a device or in a UIWebView.
  • it doesn't like spaces around the separators in the JSON.

Here's what it looks like enabling the inspector in MobileSafari using gdb and running the 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}
like image 147
also Avatar answered Sep 19 '22 08:09

also