If experienced programmers actually ever use debuggers, and if so under what circumstances. Although in the answer to that question I said "months" ago I probably meant "years" - I really don't use a debugger. So my specific answerable question is under which circumstances would you, as an experienced programmer, use a debugger?
closed as not constructive by Steven A. Lowe, Walter, Macneil, Rein Henrichs, Adam Lear♦ May 21 '11 at 19:03
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. If this question can be reworded to fit the rules in the help center, please edit the question.
migrated from stackoverflow.com May 21 '11 at 16:56
This question came from our site for professional and enthusiast programmers.
I would say that not using a debugger is a sign of inexperience. Stepping through code line by line is the best way to trace the flow of execution.
I use the debugger often, because I work on a large system and therefore I suck. http://steve-yegge.blogspot.com/2007/06/rich-programmer-food.html
No matter how short and frequently-read your code is, there is always going to be a possibility that it will have bugs. http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html
To err is human and one can never prove that a program is correct, so why not use tools such as debugger / automated testing to aid ourselves in this difficult business?
If the code is short enough, then simple tests will do. Also, if it is short and you know the nature of the bug, the reading the code can be enough. However, once the code base is large, involves several languages mixed together, plus 3 tiers, then you simply must have good test coverage on many levels plus a very good debugger - otherwise you will be wasting a lot of time.
So, when do I not need a debugger?
I am not the smartest coder, nor the most experienced, but still, sometimes I do not need to use the debugger. That is when:
- The code is mine or well-written AND
- It is written in a readable language AND
- The overall project is small.
When do I rely on a debugger heavily?
- Short Answer: often.
- When an application crashes. Particularly when it is deployed. Having VS2010 installed on that computer can make a difference between "Unknown Error" and
- When a 3rd party library crashes or misbehaves.
- When the code is poorly written. Particularly if the same file was touched by 10 different people in the last 10 years, 7 of which are no longer with the company.
- When the project is large
- When the code is rather monolithic.
- When there are several tiers (GUI, SQL, BL) involved.
Note that "debugger" can refer to more than one tool. I use Visual Studio debugger, SQL debugger (mostly for stored procs) and SQL profiler as well (to figure out which SP are being called). Would I need tools of this caliber I were writing a quick sysadmin-ish Python script? No. If I made my own little GUI-based tool? Depends. If it is .Net WinForms - probably not. If it is WPF - yes.
What defines a "real" programmer anyway? One that is quick? knowledgeable? Is good at algorithms? Writes good documentation? Just when exactly does one graduate into this new title? When does one cross the magical line?
I would say that a programmer who has not gotten his/her hands dirty in an existing 100+ man-years effort has not had a chance to be humbled by the complexity and own limitations (as well as frustrated with code quality).
I personally try to use the best debugger available to me, and I tend to use it often. If a task is simple enough and does not require a debugger - I do not use it then. It does not take too long to figure whether I need one or not.
Now, in theory I could read the code base for so long, that I would just get it. However, hands-on approach works best, plus I often want to re-write that stupid code that I am seeing. Unfortunately it would take me 10+ years to clean up the code base that I am in. So, using debugger is an obvious first step. Only when I find out just which one of 5 million lines of code is acting up, would I scan the file up and down to try to figure out what that class is doing.
"I don't like debuggers. Never have, probably never will." — Linus Torvalds
On the other hand, he doesn't have a Stack Overflow account, so I'm not sure if you are interested in his opinion :)
So my specific answerable question is under which circumstances would you, as an experienced programmer, use a debugger?
- When you're unable to "debug" by reading your code.
- When you're unable to predict what values certain variables have an a given time.
- When your mental model of your code does not fit the output given by your code
I had the fortune/misfortune of not knowing how to use a debugger in my programming journey. Thus in the past I was forced to debug without a debugger. However after learning to use a debugger -> I've become 100x more productive in finding bugs.
To give a slightly different perspective from the current answers; As an embedded software engineer working on systems that often have a real-time component I rarely use a debugger.
On occasion a debugger can be an amazing tool and whenever I am able to build and run code on a desktop then I would always use a debugger.
On chip, with real-time constraints, then there is a heavy burden associated with trying to use a debugger. As soon as you pause execution you are likely to upset, possibly fatally, the timing of the rest of the system. Generally on chip, printf in non-critical code and IO waggling in time-critical code is the best and actually simplest tool. It's not as good as a debugger, but it's much cheaper to get working with a real system.
I think experienced programmers almost exclusively use debuggers, when they are needed. What better way to track down a bug than to actually follow the execution of the code...
Are you under the assumption that the Skeets of the world don't make mistakes or just know everything? All but the most trivial programs behave in unexpected ways under some circumstances. It is a given that issues are going to have to be investigated. So the choices are use print statements, on one end of the spectrum, or look examine what happened, post mortem, on the other, or look right in the middle as the code executes and figure out what is going on.
Maybe a better way of thinking about it is that experienced programmers know when to use a debugger. In code with few dependencies looking at a stack trace is probably enough to figure out what is wrong. But there are complicated scenarios where your code is working with other code, and you need a debugger to look at the stuff you didnt write.
I don't, and I've been programming for over 10 years. I used to, when I programmed in c/c++. Now I program in java. The truth is that if you're doing logging correctly you'll end up with a stack trace which is enough for most skilled developers. Also if you're writing (good) unit tests, and functional tests, that eliminates a whole class of bugs.
Who cares? What I want to know is will using a debugger prevent me from being a better programmer in the long-run? Maybe debuggers were of lower quality when many experienced developers started so they were a hinderance. Is it a crutch that prevents deeper understanding?
Some programmer, probably better than the rest of us, found a need for a debugger and built one (No idea who created the first one.). I'm sure they were more productive as a result of it. I doubt the motivation was to enable lesser mortals to write code.
Your methods should be small/simple enough to be compiled and run by your mind, unit tests should cover functionality. If you find a bug, write a test. Run it, fix it.
I only tend to use the debugger when ive got unexpected behaviour from untestable code, like the ASP.NET framework.
In Smalltalk, I develop almost entirely in the debugger:
- Write a test that I know will fail.
- Run the test. When it fails, the debugger pops up.
- Write, in the debugger, the code necessary to make the test pass.
- Resume execution.
- If I get a green light, go to step 1 with a new failing test. Otherwise, in the debugger find out what I did wrong and fix it.
I use a debugger when I need to. That is not daily, but it does occur occasionally. It is sometimes better to step through the code to see what exactly happens.
I must admit I use debuggers less and less. I've been developing in Delphi for over 10 years. I also write stored procedures in PL/SQL. Since a couple of months, I'm a PHP developer too.
I mainly use the debugger in either of these cases if I find a piece of obscure code that was written years ago and I need to modify it. It sometimes helps to find out the exact way a program works if it is hard to read the code. In PHP that is hardly ever necessary, but in Delphi, which is event based, it sometimes helps when you got a complex framework.
But as you say, using the debugger is an exception. Most problems are solved by just reading the code and fixing any mistakes you (or someone else) made.
But that goes for stepping through code. I do quite often use the call stack when an exception occurs, and I occasionally put a breakpoint somewhere to inspect a variable. But nearly always in a piece of code that needs a thorough refactoring anyway.
I occasionally code with no debugger, but only when forced to at gunpoint, ie. legacy embedded gunge on an 8051 or Z80.
IMHO, you need a debugger and logging on any complex job. Once is not a substitute for the other. A logging system cannot help if the app stuffs in a driver, for example, where the only thing the code can do is interact with hardware and set a semaphore.
A debugger cannot help with a system error where the apps are working fine according to the way you wrote them, but the system still doesn't work because of some intermittent comms protocol error.
So, I need the debugger to remove the stupid, glaring bugs and hardware cockups. I need good logging to catch intermittent system integration bugs.
I gotta have both - I need all the help I can get!
I only use a debugger when these steps fail:
- Get the error reproducible. Think. This is often all that is needed.
- Check any stack trace and logs.
- Add more logging around the offending code.
These steps takes care of 95% of all cases. That means I rarely use a debugger, and when I do, it tends to give me too much information and I get bogged down in unrelated details. This is especially true if working on a multi-threaded, real-time system.
So judiciously placed logging statements goes a long way.
Could it simply be that very experienced programmers are the same as very old programmers, and they learned to program, and formed their habits, back when debuggers were not always available, and sometimes not very good?
If you get really good at printf debugging (and back in the eighties, we didn't have much choice but to become really good at it), perhaps a debugger doesn't add that much.
It's a question of personal choice.
Honestly I think debuggers are useful in certains situations where it helps a lot knowing what's up on your ram at any given step of your program's execution.
The primary utility of a debugger is to halt a program without the program being designed to halt itself: this feature is quite important.
Apart from those 2 features, I don't think a debugger is really necessary; any complex program you make should have some sort of "verbose" mode, i.e. telling everything it is doing with printf or std::cout, what choices it made, and a lot of other parameters.
Just imagine you make a program, and the user has a problem using it: how to know if he is using it the way it was designed to be used, or if the thing he is complaining about might be a bug?
Debuggers are like the electrical steering for your car: it's more comfortable to have one, but it won't make your drive any better.
Progamming is about design and logic, the way tools can assist you in tracking stuff doesn't make you a better programmer.
Plus debuggers are useful for compiled languages, much less for intepreted ones.