4

I've just set up realgud to use pdb and ipdb. It works fine when running a python process on my own machine. The probblem though is that when running a python process (a Pyramid web app) from within a virtualenv inside a virtual machine (using vagrant), I am setting breakpoints, but they are never being triggered. I know that using pdb-remote or ipdb-remote should work but I just can't figure out how to do so, so any help would be greatly appreciated!

The issue I am having is decsribed here but frankly I don't quite understand it.

1

As an update, I decide to go with pudb. I use multi-term to ssh into the vm and then just run the debugger from there.

1

Simple "devops" in practice, but requires a lot of words.

One feature of Emacs often overlooked - it's a terminal-based editor:
emacs -nw or the same emacs --no-window-system
(it should be launched in activated Python virtual environment)

All IDE's work only in Graphic Display mode. "Remote debugging" stems from this: a special process on a debugged machine and a communication protocol from IDE to that remote process.

Emacs being a terminal-based capable interface: using SSH launch Emacs on a debugged machine and have an unexcelled interface to it.

Local Emacs init script that installs all known by the user extensions can be transferred to the remote machine and launched from .emacs start file - replication of all user's local setups.

Realgud - debugger extension for Emacs.

To debug Python the only robust method is to insert code lines into source that invoke one of the existing debuggers for Python - inline breakpoints. Some devs believe such method "pollutes the sources", but it always works, unlike others. Python debuggers do not trap breakpoints in functions that are executed in other threads, so just setting a breakpoint in a debugger doesn't guarantee it will be trapped.

This method of debugging in realgud is called "delayed"
M-x pdb-delayed M-x trepan3k-delayed
Trepan is a debugger with a GDB-like command interface, shows threads, is more precise, but is very slow when stepping over expensive functions(like getting web response). For special cases.

These functions ask for the module path and its args to debug(default: current buffer) and create a buffer with Python process that serves as a debugger's command line interface.
When the debugged program hits a line in source: import pdb; pdb.set_trace()

that file is opened in other buffer(python-mode) with minor mode for key mappings of basic debugger commands: F10 for next, F5 continue, etc.
Hence it's "delayed".

Vagrant

If debugging is done by launching a development server like Django's:
M-x pdb-delayed ->
Emacs prompt in minibuffer: pdb /pathto/manage.py runserver(runserver added manually)

then it may require forwarded port used by the dev server to a host machine in Vagrantfile configuration:
config.vm.network :forwarded_port, guest: 8000, host: 8000

And the dev server must be launched with explicit IP:PORT(for Virtualbox provider in Vagrant that IP must be 0.0.0.0, not 127.0.0.1):
pdb /pathto/manage.py runserver 0.0.0.0:8000

What if the debugged source must serve website users?

M-x pdb-delayed ->
Emacs minibuffer prompt: ./pdb /pathto/manage.py runserver("runserver" added manually)
Where ./pdb is a shell script in project's directory:

#!/bin/sh  
AKDEBUG=on python -m pdb $*

So debugger's buffer process will have AKDEBUG environment variable defined, and a breakpoint in python source would be then:

import os
if os.getenv('AKDEBUG'):import pdb;pdb.set_trace()

Debugger will be triggered only for the dev Django server.
Similar principle for any other framework.

Some convenient tools

M-x rgrep - recursive search for breakpoint lines in code.
Standard Abbrev extension: to insert inline breakpoints.
So that typing "pd"(for example) and space, would expand to:

import os
if os.getenv('AKDEBUG'):import pdb;pdb.set_trace()

In Emacs init, inside Python mode hook:

(define-abbrev python-mode-abbrev-table  "pd" "import os
if os.getenv('AKDEBUG'):import pdb;pdb.set_trace()
" 'some-function-to-indent-this-abbrev-expansion)

(defun some-function-to-indent-abbrev-expansion ()
  (forward-line -1)
  (funcall indent-line-function)
  (move-end-of-line 1)
  (save-buffer 0))

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.