How to properly debug a python3.3 curses application using pdb? - python

When using pdb to debug a curses application, the interactive debugger is useless, since curses messes up the terminal screen. Debugging post mortem works though, but that is a bit limited.
So what we probably need is having the debugger work in a terminal separately from the debuggee (the application that is being debugged).
Some alternatives which apply remote debugging (such as xpdb) appear either not to work with python 3.3 or give weird errors for other reasons.
So how can I use pdb in a different terminal, or in another proper way?

Use some debugger's functionalities for attach to a running process. For instance you can try:
gdb python <pid>
See how here Python Wiki DebuggingWithGdb.
being the pid of the process you want to debug. Also there is WinPdb that allows you to connect to a remote or local process. WinPdb is well documented and I think is your best option.

I've found that this bit of advice from the Python documentation helps:
A common problem when debugging a curses application is to get your
terminal messed up when the application dies without restoring the
terminal to its previous state. In Python this commonly happens when
your code is buggy and raises an uncaught exception. Keys are no
longer echoed to the screen when you type them, for example, which
makes using the shell difficult. In Python you can avoid these
complications and make debugging much easier by importing the module
curses.wrapper. It supplies a wrapper() function that takes a
callable. It does the initializations described above, and also
initializes colors if color support is present. It then runs your
provided callable and finally deinitializes appropriately. The
callable is called inside a try-catch clause which catches exceptions,
performs curses deinitialization, and then passes the exception
upwards. Thus, your terminal won’t be left in a funny state on
exception.
Please see here for info.

Related

How do I debug through a gdb helper script written in python?

there may very well be an answer to this question, but it's really hard to google for.
you can add commands to gdb by writing them in python. I am interested in debugging one of those python scripts that's running in gdb session.
my best guess is to run gdb on gdb and execute the user added command and somehow magically break on the python program code?
has anybody done anything like this before? I don't know the mechanism by which gdb calls python code, so if it's not in the same process space as the gdb that's calling it, I don't see how I'd be able to set breakpoints in the python program.
or do I somehow get pdb to run in gdb? I guess I can put pdb.set_trace() in the python program, but here's the extra catch: I'd like to be able to do all this from vscode.
so I guess my question is: what order of what things do I need to run to be able to vscode debug a python script that was initiated by gdb?
anybody have any idea?
thanks.
so I figured it out. it's kinda neat.
you run gdb to debug your program as normal, then in another window you attach to a running python program.
in this case the running python program is the gdb process.
once you attach, you can set breakpoints in the python program, and then when you run commands in the first window where the gdb session is, if it hits a breakpoint in the python code, it will pop up in the second window.
the tipoff was that when you run gdb there does not appear to be any other python process that's a child of gdb or related anywhere, so I figured gdb must dynamically link to some python library so that the python compiler/interpreter must be running in the gdb process space, so I figured I'd try attaching to that, and it worked.

Any command like '%debug' (in jupyter) when running python script?

In jupyter, when an error occurs, we can continuously debug the error with the command %debug. I want to know if there is the similar way in running python script (.py) in the shell.
I know that I can use pdb to make some break points, but I just want to know the way without such a pre-processing (because re-running the code until the error costs a lot of time).
In general, no: it depends on "the shell" that you are running. Jupyter launches with a lot of instrumentation in support of its debugger, assuming that you're using Jupyter because you want those capabilities at the ready.
I presume that you're using some UNIX shell (since you mention pdb); implicitly loading superfluous software is antithetical to the UNIX philosophy.
I think that what you'll need is one of the "after" debugger modes, although that will still leave you without information from just before the error point: those packages cannot do much to trace the history of problem variables.

Python debug: How to step into another python scripts?

I have a python script that runs well. It invokes another scripts like this:
os.system('python creep.py '+ str(time)+' ' +str(date) +' '+name_sample)
How can I step into the script "creep.py" when I debug it with pdb?
You can't. That script is running in a separate process. pdb doesn't have any special capability to recognize executables as Python interpreters and "attach" to scripts they may be running.
You shouldn't be shelling out to run another script though... better to just import it and call its methods directly.
I agree with kindall that it is a good idea to try importing the other script and calling its methods directly. This will hopefully get rid of your problem, and also it will be easier to trace errors while debugging in the future.

How can I make python go into interactive mode only if it dies on exception?

Is there a way to invoke a python program such that it will run normally if it does not die, but if it has an uncaught exception, to behave as though it were run with -i?
The reason is that I am running my python program from an external script, and it does not encounter the exceptional condition until several runs in. So I want to just lazily go into interactive mode so I can then load up the debug module and look at the postmortem to see the stack variables, but not to have it fall into the interactive prompt for all the earlier runs of the program which do succeed.
Stuff a function into sys.excepthook that creates a console using code.

How can I save / copy classes & functions I've written in the python interpreter?

How can you save functions/ classes you've writing in a python interactive session to a file? Specifically, is there a way in pydev / eclipse's interactive session (on a mac) to do this?
I just started learning python - and am enjoying using the interpreter's interactive session for testing and playing with modules I've written. However, I find myself writing functions in the interpreter, which I think, oh it would be cool to save that to my script files. How do I do this?
I tried:
import pickle
pickle.dump(my_function, open("output.p", "w"))
But it seems to be more of a binary serialization, or at least nothing that I could copy and paste into my code...
Are there ways to see the code behind classes & functions I've defined in the interpreter? And then copy them out of the interpreter?
Update:
Ok, here's what I've learned so far:
I missed the easiest of all - PyDev's interactive session in eclipse allows you to right click and save your session. Still have to remove >>>'s, but gets the job done.
IPython is apparently the way to go to do this.
How to save a Python interactive session? has more details.
The best environment for interactive coding sessions has to be IPython, in my opinion. It's built on and extends the basic Python interpreter with a lot of magic, including history. For example, you can issue the command %logstart to dump all subsequent input to a file, which still needs to be edited afterward before it will be a script, but gives you a lot to work with.
When installing IPython, don't forget pyreadline.
In general, however, it is best to write code in an IDE and then run it. IPython helps here as well. If you write and save the script, then use the IPython "run" command to run it, the entire global namespace of the script will be available for inspection in your IPython session. Additionally, you can use the -d argument to run to trigger the pdb debugger immediately on any unhandled exception.
If you're more of a straightlaced IDE and debugger kind of guy, then the easiest and best lightweight environment has to be PyScripter.
I think the answer is to change your workflow.
What I do is write my functions in an editor (emacs), and then press a key combination (Ctrl-c Ctrl-e) to send the region of text to the (i)python interpreter.
That way I can save the function if I want, and also play with it in an interpreter.
Emacs is central to how I do it, but I'm sure there must be similar approaches with many editors (vim, gedit, etc) and IDEs.
PS. Finding a good editor is crucial when working with Python. The editor must be able to move blocks of code to the left and right easily, or the whitespace issue becomes too onerous.
I dislike typing blocks of code in the python interpreter because it doesn't allow me to shift blocks easily. You'll like Python even more when you find the right editor.
You can setup a python history file which stores everything you type into the interpreter.
Here's how:
http://docs.python.org/tutorial/interactive.html
I think it can't be done.
Python can perform instrospection with the inspect module, but the inspect.getsource function won't work without a source file.

Categories

Resources