3 Debugging
Maximilian Hils edited this page 2015-03-14 01:50:08 +01:00

Pro Tip: Rather than debugging mitmproxy, debug mitmdump using your regular tools!

Debugging mitmproxy is best done in "remote" mode, as the terminal that starts mitmproxy is used by the Urwid library to render the interface.

Modify mitmproxy to connect to a remote debugger

Add the debugger import

from pydev import pydevd

Attempt to connect on launch

if __name__ == '__main__':
    try:
        pydevd.settrace('localhost', port=1234, suspend=False)
    except:
        print >> sys.stderr, "mitmproxy: failed to connect to remote debugger."

Here, suspend=False will allow mitmproxy to start up and run until hitting a breakpoint.

IDE Configuration

I've used IntelliJ IDEA Ultimate with the Python (PyCharm) plugin installed. PyCharm installs an egg with the required pydev module imported in the steps above.

In "Run/Debug Configurations", add a new "Python Remote Debug" configuration with settings matching the settrace() added in the steps above. Name it "mitmproxy Remote"

Save and start the "mitmproxy Remote" configuration. It will wait for connections:

Starting debug server at port 1234
Waiting for connection...

Run mitmproxy

To ensure the pydev module is both found, and the correct version, configure your terminal $PYTHONPATH to include the PyCharm egg. If you don't have $PYTHONPATH already configured, you can set it to the path of the PyCharm egg.

On Mac OS X, this looks like:

$ PYTHONPATH=~/Library/Application\ Support/IntelliJIdea11/python/pycharm-debug.egg
$ echo $PYTHONPATH 
/Users/robwills/Library/Application Support/IntelliJIdea11/python/pycharm-debug.egg

This environment variable will only persist for the current terminal session. Other terminals, including all new terminal sessions will not have this configuration. To make it permanent, add it to your shell configuration (typically ~/.profile).

Now starting mitmproxy should connect to the "mitmproxy Remote" configuration started in the IDE.

$ ./mitmproxy -p 8888 2>/tmp/mitmproxy.err

Note that redirecting STDERR will prevent drawing glitches when output is written to STDERR.

Back in the IDE debugger Console view, confirmation of the debugger connection:

Connected to pydev debugger (build null)

Set a breakpoint somewhere to verify that the session is working. e.g. libmproxy/console/flowlist.py at self.master.clear_events()

class EventListBox(urwid.ListBox):
    def __init__(self, master):
        self.master = master
        urwid.ListBox.__init__(self, master.eventlist)

    def keypress(self, size, key):
        key = common.shortcuts(key)
        if key == "C":
            self.master.clear_events()
            key = None
        return urwid.ListBox.keypress(self, size, key)

Now, in mitmproxy show the event view "e", then clear it "C". Your debugger should now be triggered.