Getting control of `pdb` back from App Engine in Emacs - python

I have a Python Google App Engine application I'd like to debug on the dev server, in Emacs. I have a pdb executable file I created so that debugging would play nice with Emacs:
$ which pdb
/usr/bin/pdb
$ cat /usr/bin/pdb
#/bin/sh
exec python -m pdb "$#"
In Emacs, I M-x pdb and get prompted Run pdb (like this): to which I enter pdb /usr/local/bin/dev_appserver.py /Users/[person]/path/to/app/directory.
This starts off nicely. I get a window with a (Pdb) prompt, I can set breakpoints successfully in early parts of the code like some of the dev_appserver.py file and use commands like n to step through line at a time. I can then enter c to continue with program execution.
Problem is, as soon as app engine has printed out its usual startup INFO messages (to the same buffer the Pdb session is taking place in), I don't get a (Pdb) prompt back again, so I can't enter any more pdb commands. This is both my first time using pdb and my first time debugging in Emacs, so maybe I'm just doing something plain wrong.

#TimHoffman has a good answer. The dev server re-routes pdb from the various actual server processes, so you're not going to be able to launch pdb from the command line.
An alternative which might work is to launch the dev server from your emacs command line without pdb, and insert a pdb breakpoint in your code
import pdb
pdb.set_trace()
I typically debug with this, but not via emacs.

Related

emacs python pdb hang

I have successfully used
M-x pdb
and then type in
python -m pdb myscript.py
and step thru my code before when i have a linux box. Now i have to do all my work in windows. I have downloaded Vincent Goulet's emacs window disbribution and Anaconda2 Python distribution and while all the python shell is working the same M-x pdb step thru my code is not working.
Precisely what happen is that i put in
M-x pdb
Then ask Run pdb (like this):
I try all 3
1) python -m pdb my_script.py
2) python my_script.py
3) my_script.py
i get a new buffer *gud-my_script.py*
in it is
Current directory is c:/User/my_user_name/Documents/python
then it just hang there.
I also try other pdb use case (i.e in script my_script2.py, i wrote)
import pdb; print "hello world1"; pdb.set_trace(); print "line 2"
then just in emacs window command promot run
python my_script2.py
the command promot will not even shows "hello world1" and just freeze there and command prompt won't return
the strange thing is that if i run this NOT in emacs and just in windows command CMD then it will work. i.e. it will print "hello world1" and then drop into debugger.
i did not making any special entry in .emacs after i downloaded Anaconda so to be honestly i don't even know which python mode i am in and why emacs is preventing interaction to show up from pdb.set_trace()
there is similar problem in stack exchange. except i am not doing google app development. Mine is a minimum example.
emacs pdb just hang

python debugging point equivalent to Perl $DB::single=1

I am a Perl programmer learning Python. I am writing my code in emacs debugging with python -m pdb script.py using Python 2.7.3.
I would like to know what is the python equivalent to in Perl adding a $DB::single=1;1; to a specific line of python code, so that when running the debugger, it will stop there, even if it's a different source code file from where the execution started (e.g. a line of code in a library being used by script.py).
Any ideas?
EDITED: after looking at pdb.set_trace() or ipdb.set_trace(), I consider them good solutions but not 100% identical to the behaviour of $DB::single=1;1;. This is, I would like the breakpoint to be on the set_trace line, instead of the next line. This is accomplished in Perl's $DB::single=1; by adding another statement in the same line: 1;, which makes it $DB::single=1;1;.
Using set_trace(), I get the breakpoint at the line after the statement, even if I add 1; after it. Still not fully understanding how Python treats multi-statement lines in comparison to Perl.
Anybody?
Any ideas?
Is the following satisfying your needs ?
import ipdb; ipdb.set_trace()
just write it somewhere in your code and run your script with python script.py.
you need the ipython debugger (ipython is an enhanced python interpreter):
pip install ipdb
edit: did you know that if you run M-x pdb RET pdb myscript.py RET, you'll have a pdb prompt and emacs will track the source code in another buffer, but it doesn't stop where you defined ipdb.set_trace() ?
Virtual Env ?
if you use virtual envs, you have a couple of options. I recommand installing virtualenvwrapper from ELPA and run M-x venv-workon.
Python comes with debugger called pdb. To stop a script at given point in code put the following
import pdb; pdb.set_trace()
Since you are using emacs, you would may want to try out the command pdb provided by gud.el (correction: You do not need to preload 'python-mode' to run pdb, thanks #Andreas Röhler for correction) . Start it by pdb name_of_script.py, then you can set breakpoint from emacs by pressing C-xSPACE at the line you want to set breakpoint at. I recommend you to use menu-bar to explore the commands provided by the debugger (GUD). You can also use the usual pdb commands in the *gud-pdb* buffer started by emacs.

Nice general way to always invoke python debugger upon exception

I'd like to have my debugger run post_mortem() any time an exception is encountered, without having to modify the source that I'm working on. I see lots of examples that involve wrapping code in a try/except block, but I'd like to have it always run, regardless of what I'm working on.
I worked on a python wrapper script but that got to be ugly and pretty much unusable.
I use pudb, which is API-equivalent to pdb, so a pdb-specific answer is fine. I run code from within my editor (vim) and would like to have the pm come up any time an exception is encountered.
It took a few months of not doing anything about it, but I happened to stumble upon a solution. I'm sure this is nothing new for the more experienced.
I have the following in my environment:
export PYTHONUSERBASE=~/.python
export PYTHONPATH=$PYTHONPATH:$PYTHONUSERBASE
And I have the following file:
~/.python/lib/python2.7/site-packages/usercustomize.py
With the following contents:
import traceback
import sys
try:
import pudb as debugger
except ImportError:
import pdb as debugger
def drop_debugger(type, value, tb):
traceback.print_exception(type, value, tb)
debugger.pm()
sys.excepthook = drop_debugger
__builtins__['debugger'] = debugger
__builtins__['st'] = debugger.set_trace
Now, whether interactively or otherwise, the debugger always jumps in upon an exception. It might be nice to smarten this up some.
It's important to make sure that you have no no-global-site-packages.txt in your site-packages. This will disable the usercustomize module with the default site.py (my virtualenv had a no-global-site-packages.txt)
Just in case it would help others, I left in the bit about modifying __builtins__. I find it quite handy to always be able to rely on some certain tools being available.
Flavor to taste.
A possible solution is to invoke pdb (I don't know about pudb, but I'll just assume it works the same) as a script:
python -m pdb script.py
Quoting the the documentation:
When invoked as a script, pdb will automatically enter post-mortem
debugging if the program being debugged exits abnormally. After
post-mortem debugging (or after normal exit of the program), pdb will
restart the program.
A solution for pdb since Python 3.2 is to start the program under the debugger via -m pdb and tell pdb to continue via -c c:
python3 -m pdb -c c program.py
Quoting the pdb documentation:
When invoked as a script, pdb will automatically enter post-mortem debugging if the program being debugged exits abnormally. After post-mortem debugging (or after normal exit of the program), pdb will restart the program.
As-of pudb 2019.2: according to the pudb documentation, the official way involves changing your code a bit (and even then, I don't end up in post-mortem mode if I just run python3 program.py!):
To start the debugger without actually pausing use:
from pudb import set_trace; set_trace(paused=False)
at the top of your code. This will start the debugger without breaking, and run it until a predefined breakpoint is hit. You can also press b on a set_trace call inside the debugger, and it will prevent it from stopping there.
Although it is possible to start the program properly under the debugger via python3 -m pudb.run program.py, pudb's command-line args do not support anything like pdb's -c c. The pudb's --pre-run=COMMAND is for external commands, not pudb commands.
What I currently do is run python3 -m pudb.run program.py without mentioning pudb or set_tracein program.py at all and press c on the keyboard. This way pudb enters its post-mortem mode upon any unhandled exception. This however only works well when I know that the exception will be reproduced. For hunting down sporadically occuring exceptions I go back to the pdb solution.

Run pdb without stdin/stdout using FIFO

I am developing FUSE filesystem with python. The problem is that after mounting a filesystem I have no access to stdin/stdout/stderr from my fuse script. I don't see anything, even tracebacks. I am trying to launch pdb like this:
import pdb
pdb.Pdb(None, open('pdb.in', 'r'), open('pdb.out', 'w')).set_trace()
All works fine but very inconvenient. I want to make pdb.in and pdb.out as fifo files but don't know how to connect it correctly. Ideally I want to type commands and see output in one terminal, but will be happy even with two terminals (in one put commands and see output in another). Questions:
1) Is it better/other way to run pdb without stdin/stdout?
2) How can I redirect stdin to pdb.in fifo (All what I type must go to pdb.in)? How can I redirect pdb.out to stdout (I had strange errors with "cat pdb.out" but maybe I don't understand something)
Ok. Exactly what I want, has been done in http://pypi.python.org/pypi/rpdb/0.1.1 .
Before starting the python app
mkfifo pdb.in
mkfifo pdb.out
Then when pdb is called you can interact with it using these two cat commands, one running in the background
cat pdb.out & cat > pdb.in
Note the readline support does not work (i.e. up arrow)
I just ran into a similar issue in a much simpler use-case:
debug a simple Python program running from the command line that had a file piped into sys.stdin, meaning, no way to use the console for pdb.
I ended up solving it by using wdb.
Quick rundown for my use-case. In the shell, install both the wdb server and the wdb client:
pip install wdb.server wdb
Now launch the wdb server with:
wdb.server.py
Now you can navigate to localhost:1984 with your browser and see an interface listing all Python programs running. The wdb project page above has instructions on what you can do if you want to debug any of these running programs.
As for a program under your control, you can you can debug it from the start with:
wdb myscript.py --script=args < and/stdin/redirection
Or, in your code, you can do:
import wdb; wdb.set_trace()
This will pop up an interface in your browser (if local) showing the traced program.
Or you can navigate to the wdb.server.py port to see all ongoing debugging sessions on top of the list of running Python programs, which you can then use to access the specific debugging session you want.
Notice that the commands for navigating the code during the trace are different from the standard pdb ones, for example, to step into a function you use .s instead of s and to step over use .n instead of n. See the wdb README in the link above for details.

Debugging python programs in emacs

How do I debug python programs in emacs? I'm using python-mode.el
I've found references suggesting:
import pdb; pdb.set_trace();
but I'm not sure how to use it.
Type M-x cd to change directory to the location of the program you wish to debug.
Type M-x pdb. You'll be prompted with Run pdb (like this): pdb. Enter the name of the program (e.g. test.py).
At the (Pdb) prompt, type help to learn about how to use pdb.
Alternatively, you can put
import pdb
pdb.set_trace()
right inside your program (e.g. test.py). Now type M-x shell to get a shell prompt. When you run your program, you'll be dumped into pdb at the point where pdb.set_trace() is executed.
For me, I needed to replace the default "pdb" with
python -m pdb myscript.py
The realgud package (available from MELPA) supports PDB (among a gazillion other debuggers), and has a host of neat features that Emac's PDB doesn't have.
The one I like best is the shortkeys mode. Once you start debugging a program, you can press n, s, c etc. right in the source window, instead of having to type these commands in the PDB buffer. It also supports Visual-Studio style keybindings with function keys (f10, f11, f5, etc).
After installing RealGUD, you need to run M-x load-feature realgud to load it, and you can start pdb with M-x realgud:pdb.

Categories

Resources