WinpdbDocs > EmbeddedDebuggingDoc
Embedded Debugging
Normally you would start a debug session by launching a script from the debugger. However, in some scenarios this is not possible. For example python scripts that are embedded in other programs. You can still debug embedded scripts by using the following technique:
Add the following line to any script you wish to debug with the embedded debugging technique:
import rpdb2; rpdb2.start_embedded_debugger(password)
Once this line is invoked, the script will freeze for a default period of 5 minutes, waiting for a debugger to attach. The password is used to secure client/server (debugger/debuggee) communication. Naturally, the debugger has to use the same password in order to successfully attach.
Interactive Passwords
It is recommended not to use a hard coded password in a script, since anyone with read access rights to the script may read the password and compromise your system security. Instead it is preferable to query the password interactively. If applicable you can use the following line as an alternative to the one suggested above:
import rpdb2; rpdb2.start_embedded_debugger_interactive_password()
Embedded Timeout
What if for any reason you fail to attach to the frozen script? The frozen script waits for you to attach for a default period of 5 minutes, and when this timeout expires it will resume execution. This prevents the need to terminate the server hosting the python script or all kinds of other desperate attempts in the hope of terminating the frozen script.
Winpdb Hang on an Inactive Embedded Interpreter
Embedded Python interpreters are not always active. Usually they become active to invoke a script method, and when this method returns they return to inactivity. During this time the embedded debugger is inactive as well. Asking Winpdb to break when the embedded Python interpreter is inactive will result in Winpdb becoming unresponsive. Once the embedded Python interpreter becomes active again, Winpdb will return to life and break into the debugged script.
Functions Definition
The relevant functions are brought here for your convenience:
def start_embedded_debugger(
pwd,
fAllowUnencrypted = True,
fAllowRemote = False,
timeout = TIMEOUT_FIVE_MINUTES,
fDebug = False
):
"""
Use 'start_embedded_debugger' to invoke the debugger engine in embedded
scripts. put the following line as the first line in your script:
import rpdb2; rpdb2.start_embedded_debugger(pwd)
This will cause the script to freeze until a debugger console attaches.
pwd - The password that governs security of client/server communication
fAllowUnencrypted - Allow unencrypted communications. Communication will
be authenticated but encrypted only if possible.
fAllowRemote - Allow debugger consoles from remote machines to connect.
timeout - Seconds to wait for attachment before giving up. If None,
never give up. Once the timeout period expires, the debuggee will
resume execution.
fDebug - debug output.
IMPORTNAT SECURITY NOTE:
USING A HARDCODED PASSWORD MAY BE UNSECURE SINCE ANYONE WITH READ
PERMISSION TO THE SCRIPT WILL BE ABLE TO READ THE PASSWORD AND CONNECT TO
THE DEBUGGER AND DO WHATEVER THEY WISH VIA THE 'EXEC' DEBUGGER COMMAND.
It is safer to use: start_embedded_debugger_interactive_password()
"""
return __start_embedded_debugger(
pwd,
fAllowUnencrypted,
fAllowRemote,
timeout,
fDebug
)
def start_embedded_debugger_interactive_password(
fAllowUnencrypted = True,
fAllowRemote = False,
timeout = TIMEOUT_FIVE_MINUTES,
fDebug = False,
stdin = sys.stdin,
stdout = sys.stdout
):
if g_server is not None:
return
if stdout is not None:
stdout.write('Please type password:')
pwd = stdin.readline().rstrip('n')
return __start_embedded_debugger(
pwd,
fAllowUnencrypted,
fAllowRemote,
timeout,
fDebug
)
An Trivial Example: Attaching to a Python Script Running Under Vim
Writing Python scripts for Vim is a great way to extend a great text editor but the smallest error and it silently breaks, which is probably a good thing but makes it hard to develop good scripts. Solution: attach Winpdb to the Python script running inside Vim.
There are two ways to run python in Vim: the first (the python command) will execute a here document and the second (the pyfile command) will run python from a file. If you store the python in a file Winpdb can load it so you can see whats going on, a good thing
I'm going to suggest you use the first method of running Python in Vim, the python command, to add a directory to the PYTHONPATH, then import a module with you code.
I put my function to debug in: ~/.vim/scripts/myScripts.py
def do():
msg = 'hello world!'
import rpdb2; rpdb2.start_embedded_debugger('foobar')
print msg
print barthen add the following to my vimrc file:
python << EOF import sys, os, vim scripts = os.environ['HOME'] + '/.vim/scripts' sys.path.append(scripts) import myScripts EOF
this one sets up the PYTHONPATH for my scripts and imports it.
function! Fooey() python myScripts.do() endfunction
this one will call my script which needs to be debugged (not really I bet you've already spotted the mistake).
Launch to Winpdb and then Vim. In the Vim terminal, type:
:call Fooey()
The script will then hang waiting for you to attach. Select File -> Attach in Winpdb and Bobs your Uncle you can debug your Vim Python scripts!
