I don't like debugging in a debugger, because I think it is often below the abstraction layer of the programming language and it is often not reproducible. I favor using unit tests when possible and I think they are a good way, but it is not always that easy to implement them. Do you know about any other alternative approaches to avoid the use of a debugger?
Think! :) - Seriously, though - before debuggers were commonly available, most people would troubleshoot their code by writing lots of state information to their output device. It still works.
Any non-trivial application should have some sort of logging/tracing facility built in to it. You'll want to be able to turn on/off various kinds of output.
It is especially helpful to log all input. It is a lot easier to reproduce issues if you can "play back" the input.
Personally, I rarely use a debugger myself. I generally find that I spend too much time single-stepping and generally messing with the mechanics before I get to the part that matters.
My favorite method of debugging is to simply add print statements at strategic places. Like, if a calculation is coming up with the wrong answer, I might add print statements to dump the values that go into the calculation.
In Java I'll normally write something like
System.out.println("In function foo: bar="+bar+", plugh="+plugh);
If the problem appears to be what path the program took through the logic, I'll add statements that print "about to enter sales calc block" or "finished writing to database" or whatever.
I only resort to a debugger when I have no clue what the problem is and I can think of nothing better than to go through every single step to see where it went wrong.
one strategy is to develop a "debug" mode, in which the application exposes several useful info, like used resources, http variables, logs, sql statements etc...
For example, I have a web app that manages the web page state thru hidden inputs, and that interacts with the database with xml messages...
when I appen a "debug=1" to the url, all hidden inputs are shown in a collapsable box, and also the executed xml-in and xml-out...
more over, in debug mode I can double-click on certain spot of the page to see the database configuration info, and there's also a shortcut to "impersonate" users, so as to test the permissions...
one of the last additions is a collapsable box that shows me the time it tok to build the whole page, and the time it took to access the database
on the database side, we process that xml and generate several sql statements. If I append an xml tag <show-sql>1</show_sql> instead of executing the query I get the sql statement... so I can "debug" the stored procedure from the sql console...
you can develop all these things in a couple of days, and I can assure you it really pays off...
to get and idea of what I'm talking about, you can have a look at the developer front end proveide by the symfony framework
http://www.symfony-project.org/book/1_0/16-Application-Management-Tools
it let's you inspect several things, like logged info, request and response contents, actions executed, etc...
in short, prepare your app to be easyble inspected...
- Testing != Debugging != Logging
- Avoid using a debugger is not realistic. Eventually you have to learn certain debugging techniques to fix difficult bugs.
Print linestm I think is by far the most used way to debug.
You know:
log("Starting transaction for client id %s", id )
Always make sure you use a good logging framework, otherwise your logs will become useless.
Design by contract, unit tests and these kinds of things help you ensure that a block of code, most often a function, works as it should. It's good for that, but it doesn't replace debugging.
Debugging means to find out why a block of code doesn't behave as it should. A unit test can only tell you that a block doesn't work as it should, it can't tell you why. To find out why, you have to step through the code line by line, tracing where the state differs from what you expect or where the logic branches unexpectedly. To trace these things, you need to inspect the state at any given time. You can do this with print
statements, using them to get variable states or to infer logic branching. A debugger is a tool that helps you do both without changing the code.
You'll have to use either one. Even a unit test is basically a print
statement that's automatically checked for correctness, just at a different level of granularity.
You seem to want to make code fix itself without looking at it. You can put tests and contracts around your code all you want, if these things tell you there's a bug in your code, eventually you'll have to look at it. If you want to inspect the code without altering it by putting in print
statements, the only tool left is the debugger. Unless there's a major breakthrough, that's the state of the art.
A debugger is a tool saying I want to avoid a debugger is like a carpenter saying I want to avoid a hammer. You are better of asking the question When should I avoid using the debugger?
Times when you should avoid using the debugger,
- When you have no idea what the code is doing, understand first then try debugging otherwise your wasting your time
- The issue is timing related (raceconditions, problems with IPC or threads), if it is a timing condition and you start single stepping, then you might not reproduce your problem.
I am sure there are other times when using a debugger is a bad idea, but my point is your question is wrong. Don't ask how do I not use the debugger but ask when should I/shouldn't I use the debugger.
my 2cents