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
)

30 Comments so far

alek314 on
August 13th, 2008

it looks like pdb.set_trace()
but both of these method have to insert code into the script file.
it would be nice if we can attach Winpdb to the python VM in the C app, and set break point in Windpdb

alek314 on
August 13th, 2008

beware, if you run into the “can not import _socket” problem, make sure you got both _socket.pyd and _socket_d.pyd at hand

There is no public API for that but you may be able to use the following function which returns the number of attached clients:

rpdb2.g_debugger.get_clients_attached()

(In Winpdb more than one debugger client (console) can attach at the same time)

Ranec on
December 3rd, 2008

So I see that some heartbeats come in form the clients.
Is there anything that comes in when a client detaches?

-R

Rudy on
January 1st, 2009

Hello,
I am trying to debug a Python macro in the moinmoin wiki. It is possible to use the standard “pdb” debugger with “import pdb; pdb.set_trace()”, but it is very abstract. Then I found Winpdb. It is great that an “embedded-debugging” mode is available. My first experience:

For beginners it would be nice to document:
import rpdb2; rpdb2.start_embedded_debugger(’password’)
If you write the password without quotes, it will not work and you see no error message. Hence, I first had to debug rpdb2 with pdb to figure that out!

Next it would be nice to mention how you start:
Menu File/Attach/ “localhost”, klick on file waiting on the statement:
import rpdb2; rpdb2.start_embedded_debugger(’password’) # debug

Then it works, very well on the fist look, now let’s see how well.
Rudy

Irfan on
February 17th, 2009

Is it possible to remotely embed the debugger. Like if the debugger is running on different machine than the actual script.

Sure, from the Winpdb GUI you can attach to a script on a remote host. Just make sure you start the embedded debugger with the fAllowRemote flag set to True so it accepts remote connections.

Hari on
March 27th, 2009

Very nice, was able to debug a python program running as a windows service by using the embedded debugging technique.

fonsch on
April 24th, 2009

quick beginner question here:

I used the embedded debug technique with a lot of success on some of my own Blender-scripts. The password was hard coded in the script (no-one but me comes near this pc, so that didn’t really matter). The password is just my name, so nothing special there.

Since I upgraded to Ubuntu 9.04 (I have no idea which packages have all changed), I get the following error message when executing the unmodified script:

File “/var/lib/python-support/python2.6/rpdb2.py”, line 13816, in __start_embedded_debugger
raise BadArgument(STR_PASSWORD_BAD)
rpdb2.BadArgument: The password should begin with a letter and continue with any combination of digits, letters or underscores (’_'). Only English characters are accepted for letters.

Hi nir,
I’ve just trtied embedded debugger and it works quite well.
I’ve got only one issue:
My app invoke some thread at startup.
If I debug my app like “winpdb myapp”. I can debug them.
On the other side I embed the debugger it could not see the previously invoked thread.
Is there a way to declare the threads to the embedded debugguer, so it could track them?

Laurent on
November 21st, 2009

Ha just found howto make my thread appears.
I’ve added as suggested in your doc:
rpdb2.settrace()

in the thread’s run loop.

And now I see them!

The only question that remains is that they where invoked via threading module
so i suspect they were not detected due to post debugger invocation.

araud on
December 15th, 2009

Did anyone managed to attach to local process from console?

I am under windows trying this scenario:
c:/temp/test.py contains:
import rpdb2; rpdb2.start_embedded_debugger(”123″)
I run it by double-clicking.
A can attach manually thru gui. But can’t get command line working:
winpdb –attach=test.py –pwd=123 –host=127.0.0.1

[...] when a debugger is needed pdb is a good equivalent to gdb. If you prefer a graphical debugger, winpdb works well and also allows you to attach to a running [...]

vit on
January 6th, 2010

Hi,

I was trying to use winpdb to debug XULRunner/pyXPCOMExt application, but whenever I’m connecting to the script, I’m getting the following message:

“Failed to load source file ‘chrome://appname/content/main.py’ from debuggee.
You may continue to debug, but you will not see source lines from this file.”

The Namespace/Threads/Stack panels are populated with correct inspectable data though. I was trying to load the source file and set a breakpoint, but winpdb would not stop on the breakpoint in this case.

vit on
January 6th, 2010

Update: after some poking around I managed to make it work by creating a source provider that would read chrome:// URLs. I’m happy now! Thanks for great work!
By the way, it looks like the documentation on this page is not up do date.

Henrik Vendelbo on
May 1st, 2010

This doesn’t seem to work on PyPy

Are you forgetting to close files ?

I get OSError, [Errno 24] Too many open files trying to use it with PyPy 1.1 on OS X

Tom Gaulton on
September 9th, 2010

I’m trying to use winpdb to debug a python scripts embedded in my own application. I can connect and view the callstack, globals, etc. initially but I’m having problems getting breakpoints to halt execution.

When my breakpoint is hit the status bar in winpdb briefly switches to ‘WAITING AT BREAKPOINT’ then immediately switches back to ‘RUNNING’. Occasionally (perhaps 1 in 50 times) the breakpoint works correctly, however if I try to use ‘Step Into’ or Next’ the status switches back to ‘RUNNING’ again.

Has anyone else had this problem? Is there something that might be happening in my application that causes it? The scripts are executed using PyRun_SimpleString() and always execute on the same thread I called rpdb2.start_embedded_debugger() from.

Any help or advice appreciated, the tool looks to be exactly what I need and is tantalizingly close to working

Perry on
September 14th, 2010

i am trying to attach to a python script used by gdb under eclipse to pretty print qt4. I see the .py file in the attach window of winpdb, with the correct path, but when i click it, it says:

Failed to attach to foo.py
Failed to find script

any idea what i am doing wrong? I was so happy to get it running so far =8(

Thouis Jones on
September 16th, 2011

I’d like to use rpdb2 to debug worker processes in a multiprocessing application. I can’t seem to figure out how to start the debugger in multiple processes, though. I know about “fork parent” and “fork child”, but what I’d really like is for both processes to end up running the debugger.

I tried to start debugging in the children after the fork (in the target of multiprocessing. Process()) using rpdb2.start_embedded_debugger(), but haven’t had any luck. Exceptions seem to just pass by the rpdb2 excepthook.

Any suggestions?

Thouis Jones on
September 16th, 2011

I should be more clear. I can call start_embedded_debugger() in an “except:” clause, can connect to the debugee, but cannot find how to debug the exception being handled.

Such a are good all over again routines wherein means that we can take it easy the actual spinal cord as well as sleep thoroughly without the practical experience in regard to overload of your all over again.

To save typing I would like to automate starting winpdb and then immediately attach with a given password. I am attaching to an embedded script that is already waiting for the attach, so cannot specify a filename. Is there a command line option that lets me do this, or another way?

Thanks,
Klaus

Bill Zhang on
August 7th, 2013

I am trying to use rpdb2.start_embedded_debugger() to attach child process but it does not work. What I am doing is write a Process class and call this function at the beginning of MyProcess.run(). I have turn on “fork parent auto” when attaching to parent process. It looks like the reason is some global variable such as rpdb2.g_debugger is not reset by the child process after forking.

>>> execfile(r”C:\tmp\script.py”)
then I can set break points, step line by line, but variables are not visible in Locals nor Globals namespace and if I do something like eval a, then it says that ‘a’ is not defined, even if I just stepped by a line in setting ‘a’ to a value.