How do I start up remote debugging with PyCharm?

John Mee picture John Mee · Aug 9, 2011 · Viewed 49k times · Source

I'm trying to get debugging up between PyCharm (on windows host) and a debian virtual host running my django application. The instructions say to install the egg, add the import, and then invoke a command. I assume these things need to be done on the debian host?

Ok, then, in what file should I put these two lines?

from pydev import pydevd
pydevd.settrace('not.local', port=21000, stdoutToServer=True, stderrToServer=True)

I tried putting it into the settings.py but got this kind of thing...

File "/django/conf/__init__.py", line 87, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
File "/django/utils/importlib.py", line 35, in import_module
    __import__(name)
File "/settings.py", line 10, in <module>
    pydevd.settrace('dan.local', port=21000, stdoutToServer=True, stderrToServer=True)
File "/pycharm-debug.egg/pydev/pydevd.py", line 1079, in settrace
    debugger.connect(host, port)
File "/pycharm-debug.egg/pydev/pydevd.py", line 241, in connect
    s = StartClient(host, port)
File "/pycharm-debug.egg/pydev/pydevd_comm.py", line 362, in StartClient
    sys.exit(1)
SystemExit: 1

Whilst pycharm just sat there "waiting for connection"

Answer

John Mee picture John Mee · Aug 15, 2011

PyCharm (or your ide of choice) acts as the "server" and your application is the "client"; so you start the server first - tell the IDE to 'debug' - then run the client - which is some code with the settrace statement in it. When your python code hits the settrace it connects to the server - pycharm - and starts feeding it the debug data.

To make this happen:

1. copy the pydev library to the remote machine

So I had to copy the file from C:\Program Files\JetBrains\PyCharm 1.5.3\pycharm-debug.egg to my linux machine. I put it at /home/john/api-dependancies/pycharm-debug.egg

2. Put the egg in the PYTHONPATH

Hopefully you appreciate that you're not going to be able to use the egg unless python can find it. I guess most people use easy_install but in my instance I added it explicitly by putting this:

   import sys
   sys.path.append('/home/john/app-dependancies/pycharm-debug.egg')

This is only necessary because I've still had no success installing an egg. This is my workaround.

3. setup the debug server config

In PyCharm you can configure the debug server via:

  • Run-> Edit Configurations: opens the 'Run/Debug Configurations' dialog
  • Defaults -> "Python Remote Debug": is the template to use
  • fill out the local host name and port and you'll probably want to 'use path mapping' but more on all this below...
  • "OK"

    Local host name: means the name of the server - that's the windows host machine in my case - or actually the IP Address of the windows host machine since the hostname is not known to my remote machine. So the virtual (remote) machine has to be able to reach the host. ping and netstat are good for this.

    Port: can be any vacant non-priviledged port you like. eg: 21000 is unlikely to be in use.

    Don't worry about the path mappings for now.

4. Start the debug server

  • Run-> Debug : start the debug server - choose the configuration you just created.

The debug console tab will appear and you should get

 Starting debug server at port 21000

in the console which means that the ide debug server is waiting for your code to open a connection to it.

5. Insert the code

This works inside a unit test:

from django.test import TestCase
class APITestCase(TestCase):
    def test_remote_debug(self):
        import sys
        sys.path.append('/home/john/dependancies/pycharm-debug.egg')
        from pydev import pydevd
        pydevd.settrace('192.168.33.1', port=21000, suspend=False)

        print "foo"

And in a django web application it's a bit finicky about where you put it - seems to work only after everything else is done:

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)

    sys.path.append('/vagrant/pycharm-debug.egg')
    import pydevd
    pydevd.settrace('192.168.33.1', port=21000, suspend=False)

Again that the IP address is the box where you're running Pycharm on; you should be able to ping that ip address from the box running your code/website. The port is your choice, just make sure you've told pycharm to listen on the same port. And I found the suspend=False less problematic than the defaults of, not only immediately halting so you're not sure if it's working, but also trying to stream to stdin/out which might give you grief also.

6. Open the firewall

Windows 7 firewall will, by default, block your incoming connection. Using netstat on the remote host you'll be able to see that SYN_SENT never becomes ESTABLISHED, at least not until you add an exception to the windows firewall for the application 'pycharm'.

OS/X and Ubuntu do not have firewalls to punch threw (by default, someone may have applied one later).

7. Set a breakpoint and run the code

After all that, when everything goes to plan, you can set a breakpoint - somewhere after the settrace has run - and pycharm console will show

Connected to pydev debugger (build 107.386)

and under the 'Debugger' tab the variables stack will start working and you can step through the code.

8. Mappings

Mapping tell pycharm where it can find the source code. So when the debugger says "i'm running line 393 of file /foo/bar/nang.py, Pycharm can translate that remote absolute path into an absolute local path... and show you the source code.

/Users/john/code/app/    /opt/bestprice/app/
/Users/john/code/master/lib    /opt/bestprice/lib/python2.7/site-packages

Done.