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
)
Winpdb - A Platform Independent Python Debugger
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
beware, if you run into the “can not import _socket” problem, make sure you got both _socket.pyd and _socket_d.pyd at hand
How can I register to know if the Debugger has detached from me?
-R
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)
So I see that some heartbeats come in form the clients.
Is there anything that comes in when a client detaches?
-R
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
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.
Very nice, was able to debug a python program running as a windows service by using the embedded debugging technique.
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.
any ideas why my password isn’t accepted anymore? I’d really like this wonderful tool to work again.
Thanks a lot!
fonsch,
Ubuntu 9.04 has an old outdated package of Winpdb. Try the latest version from this website and let me know if the problem still exists:
http://winpdb.org/download/
Also please use the Winpdb Google group to communicate on this issue:
http://groups.google.com/group/winpdb
Thanks,
Nir
Thanks for the quick reply nir. Upgrading winpdb didn’t help, I still get the same error. I’ll post my question at the Google group (feel free to remove my posts here if they’re out of place
)
[...] Python interpreters. I’ll give it a try with Serna, but wondered if anyone has tried this already. Winpdb - A Platform Independent Python Debugger Embedded Debugging Regards, [...]
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?
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.
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
All I receive in return is help message…
Thank you!
[...] 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 [...]
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.
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.
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
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
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(
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?
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.