Debugging is determining the point at which the program's expected behavior diverges from its actual behavior. You often don't know where where/when this is happening. Print-debugging can give you a transcript of the program's execution, which you can look at to hone in on the moment where things go wrong. Stepping through a program's execution line-by-line and checking your assumptions can be a lot slower in some cases. And most debuggers can't go backwards, so if you miss the critical moment you have to start all over again.
These are two tools in the toolbox; using print debugging does not mean you are not "a boss."
I agree though, outputting print statements at different levels of severity, i.e. warning, error, info, etc. is a great way to see if things are working on a high level. For more granularity, debuggers are invaluable to figure out why a specific portion of code isn't working as expected.
All of the JetBrains products are super smart and efficient, and the community editions are no exception.
https://www.securecoding.cert.org/confluence/display/seccode...
A condition, if set, will then apply to whether the action should or should not be applied.
The great part is they can all be combined, so you can setup a breakpoint which will pre-log the info you know you'll need then drop you in the visual debugger with all base information waiting for you.
When I read about this more, it sounds like you can make watchpoints conditional too. You could use this pattern to print a transcript of every change that happens to a data value! Though I'm not sure if the watchpoint condition has easy access to the source file/line, so it might not be easy to log what code was changing the value.
https://github.com/clojure/tools.trace
https://github.com/coventry/Troncle (I can use this from nRepl'ing into production servers)
Yes.
>Stepping through a program's execution line-by-line and checking your assumptions can be a lot slower in some cases.
Yes again, particularly when the code is in a loop. Whereas, if you use print-debugging, even though the output will be repeated as many times as the loop runs, you at least have the possibility of grepping to filter it down to relevant (e.g. erroneous/unexpected) output.
Here's a simple Python debugging function that may be useful:
http://jugad2.blogspot.in/2013/10/a-simple-python-debugging-...
import pdb; pdb.set_trace();
There's a chance you forget this, check-in, and it ends in production. Use pdb facilities instead: $ python -m pdb <myscript>
Then set a breakpoint and continue: (Pdb) break <filename.py>:<line>
(Pdb) c
This is trivial to automate from any editor or command line, so you don't even have to guess the path to the file.EDIT: For the lazy, here's a script to set breakpoints from the command line and run your scripts:
- I have a ~/.python/sitecustomize.py file with the following:
# Start debug on Exception
import bdb import sys
def info(type, value, tb):
if hasattr(sys, 'ps1') \
or not sys.stdin.isatty() \
or not sys.stdout.isatty() \
or not sys.stderr.isatty() \
or issubclass(type, bdb.BdbQuit) \
or issubclass(type, SyntaxError):
# we are in interactive mode or we don't have a tty-like
# device, so we call the default hook
sys.__excepthook__(type, value, tb)
else:
import traceback, ipdb
# we are NOT in interactive mode, print the exception...
traceback.print_exception(type, value, tb)
print
# ...then start the debugger in post-mortem mode.
ipdb.pm()
sys.excepthook = infoIt will start ipdb automatically in case of any exception on command line called scripts.
- I use the awesome pdb emacs package for debug interactivelly during bigger bug hunts (Also for dev too... It's very a nice tool)
- Buutt... I still find the "print dance" to be my first-to-use quick tool.
edit: Fixed pasted code
And obviously any test covering that line will fail/hang.
If one doesn't have an automated test process, then I suspect one has bigger potential errors that could sneak in than an errant pdb breakpoint. I'll just assume that your release / merge process DOES include a test suite that you can add this sort of test to.
Having to change the source to fire the debugger is a dumb way of debugging after all, and doesn't allow certain things (e.g., step thru a 3rd party library). Better coach the developers on how to use the tools properly.
Perhaps I should add a pre-commit hook to grep for pdb.set_trace() and reject commits with that in them.
(a) the breakpoint line doesn't move around a lot between different executions, as you edit the code;
(b) you don't want to programatically invoke the debugger (i.e. if f(x): pdb.set_trace() )
(b) Pdb supports conditions with `filename:lineno, statement`. Statement will have access to local scope. E.g.:
$ python -m manage.py runserver
(Pdb) break manage.py:11, os.environ["DJANGO_SETTINGS_MODULE"] == "myproj.settings"
Breakpoint 1 at /Users/hcarvalhoalves/Projetos/myproj/manage.py:11
(Pdb) break
Num Type Disp Enb Where
1 breakpoint keep yes at /Users/hcarvalhoalves/Projetos/myproj/manage.py:11
stop only if os.environ["DJANGO_SETTINGS_MODULE"] == "myproj.settings"
Really, it does a bunch of things. I wonder why developers are unaware of it.There are a number of different routes in Django development that you may need to debug:
1. Debugging view endpoints when not using runserver (for example when testing out your actual deploy webserver). For this, none the debuggers will work, as you have no console to run through. I combat this by using winpdb that allows remote debugging.
2. Debugging either unittest based code or when using runserver, you can use the method described by hcarvalhoalves comment.
However, I still think that in lots of cases its more powerful to import in the code. With the necessary coverage in tests, it should always be picked up.
$ python -m pdb manage.py runserver
(Pdb) break mymodule/myfile.py:42
(Pdb) cInstead I have to stick in some print statements and start everything over again.
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt: # allow ctrl-C
raise
except Exception as e:
import sys, traceback, pdb
print e
type, value, tb = sys.exc_info()
traceback.print_exc()
pdb.post_mortem(tb)
This will catch any exceptions and throw you into PDB in the context where the exception was raised. You probably don't want to leave it in production code, but it's super useful for development. $ python -m pdb yourscript.py
(Pdb) c
Will let you inspect the local scope after an uncaught exception.I've always find it interesting how the Python/Ruby community debug your code both during development (coding or writing unit-tests) and perhaps in production as well (for the record, I use "print" as my debugging tool).
I'm a long time Eclipse user who has recently converted to IntelliJ (almost a year) and the debugger that comes with these editors is something I can't live without hence I have not moved to Emacs or VI(m) or whatever the UNIX hackers use because it would crippled my productivity significantly (or so I thought, feel free to criticize my point of view).
So sometimes I'm wondering how productive Python/Ruby + VIM/Emacs users. Just an honest question really.
PS: most Java IDE debuggers can do local AND remote AND has some support for hotswap code.
When I did mostly Java coding, I would tend to use println debugging rather than dive into the IDE's debugger, as I tended to be able to zero in more easily on what was going on when I took a holistic "Let's print out each item's id and name ..." approach to start.
Now that I do most of my code in Python, I use the interactive debugger almost exclusively.
With an IDE, I can look at variables' contents. What do I do when I want to check the result of a method call, though? It is likely tool unfamiliarity, but it's never been clear how to check that as something to inspect. (If you know how to do this, then you're a much more savvy user of the IDE's debugging tools than I am.) If I don't have the right breakpoint, or the right questions, I often glean little.
Println debugging is an easy way to see that you're looping incorrectly, or that All Your Data is bad in a way you didn't expect.
With a REPL-style debugger, I can treat it as an interactive question/answer session that lets me check things like contents of the database, or the values that helper methods return:
> print len(foo.items)
0
# why??? Maybe the objects don't exist?
> print Foo.objects.filter(bar=42)
[foo1, foo2, foo3]
# Let me place a new breakpoint then in
# my JsFoo.from_db_item() method, and try again ....
I think the nicest thing about an interactive debugger is that it lets me construct arbitrary expressions -- print lists of things, look at nested data, etc -- in the language I am already developing in. I always had a hard time doing something quite as powerful in Eclipse.In Eclipse/IntelliJ you can set "Conditional Breakpoint" (only stop/break when certain conditions is met) very handy when debugging a loop. In addition to that, you can also set "breakpoint on any Exception".
Also, in Eclipse/IntelliJ, when the debugger hits the breakpoint, you could execute Java code within the context of that breakpoint (of course, java.lang is given by default in addition to the context of that breakpoint).
I've never done more complex debugging than that but I'm guessing you can write almost anything you want within the "evaluate window" in those IDEs.
As much as a UNIX System V user.
It's an early stage project, but hopefully demonstrates that there is a middle ground between "Everything in an 80x25 text window" and "500lb IDE gorilla".
(Full disclosure: I'm the core developer of Bugjar)
Also what I like to do with ipdb is set a debug point and just write new functionality in real time. Most good programmers probably do this in their heads but having a computer do it for you is the next best thing. You catch bugs almost immediately (hey this variable isn't supposed to be empty!). It feels pretty cool to send a request to a web app and just pound out the code to make it respond correctly before the browser gives up on the HTTP connection.
Not just remote debugging of a halted program - you can actually inspect and alter variables and issue commands into the executing code.
Is there a way to do that in, say, Python?
In Tcl, the program can be running its event loop at normal speed, and you can inject commands into that event loop while it runs.
Their debug cycle is a) notice something is not quite right. b) insert some print statements in the code that they just changed. c) run it again. d) look at the code and the print statements to see where they made a wrong assumption, fix it and move on.
No need for figuring out where to set a break or single stepping through too much tangle.
I thought there would actually be some innovative techniques in this article.
Perhaps a better title would be, "A review of python debuggers".
In all honesty I rarely feel the need for anything more. Generally I don't even need the print() because I stick to small self contained functions.
The exception is when I'm using a poorly documented or new to me open source library. I guess at times like that a debugger may be useful. So next time I run into such a situation I'll try out a debugger.
But I can't see much of a reason for it in my own code.
Once the weird behavior is covered, usually print debugging is even better than pdb because it will encourage you to extend the test suite.
What I would like though is a special monkey patching in python that allow my to write print like "p this that" and will prettyprint this and that on stdout
[1]: http://winpdb.org/
I'm aware there are a slew of plugins/built-ins with IDE's that I didn't cover. As I mentioned in a comment on the post, I think a disclaimer that stated my preference would have helped.
I'm interested in the number of people that do the Editor-of-Choice and PyCharm combo. May have to see how the GVIM PyCharm combo would work.
1. first listen to a socket with nc -l -U 1.sock
2. Add this to your python script.
import socket, pdb
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('1.sock')
f = s.makefile()
pdb.Pdb(stdin=f, stdout=f).set_trace()
raise wtf
3. now debug in nc. enjoy.https://news.ycombinator.com/item?id=6770412
But I'm happy. When I posted, it failed to generate a discussion. If it were identified as a dupe this time, it would probably be forgotten.
It's a great article.
Looks really good.
"There are debugger people, and then there are printf people, you see..."
This works across the internet.