Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Over the course of my career, I've noticed that some developers don't use debugging tools, but do spot checking on erroneous code to figure out what the problem is.

While many times being able to quickly find errors in code without a debugger is a good skill to have, it seems it's less productive to spend a lot of time looking for issues when a debugger would easily find little mistakes like typos.

Is it possible to manage a complex without a debugger? Is it advisable? What benefits are there to be had by using "psychic debugging?"

share|improve this question

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

18  
Hi jonathan, I've revised your question to avoid the trappings of a rant and keep the question open: I think—as worded now—it's a decent enough, answerable question. –  user8 Jan 23 '12 at 21:02

21 Answers 21

up vote 138 down vote accepted

What looks like guessing from the outside often turns out to be what I call "debugging in your mind". In a way, this is similar to grandmasters' ability to play chess without looking at a chess board.

It is by far the most efficient debugging technique I know, because it does not require a debugger at all. Your brain explores multiple code paths at the same time, yielding better turnaround than you could possibly get with a debugger.

I was not conscious about this technique before briefly entering the world of competitive programming, where using a debugger meant losing precious seconds. After about a year of competing, I started using this technique almost exclusively as my initial line of defense, followed by debug logging, with using an actual debugger sitting at the distant third place. One useful side effect of this practice was that I started adding new bugs at a slower pace, because "debugging in my mind" did not stop as I wrote new code.

Of course this method has its limitations, due mostly to the limitations of one's mind at visualizing multiple paths through the code. I learned to respect these limitations of my mind, turning to a debugger for fixing bugs in more advanced algorithms.

share|improve this answer
27  
+1 I find "programming by guessing" to be a loaded phrase. There is no substitute for thinking. What the OP does not explain is how effective the "guessing" is. My doubt is that it's purely guessing (i.e. spaghetti on the wall approach), but rather using deductive reasoning. Debuggers have their place, but they are not a panacea for deductive reasoning and simply understanding the code. –  Bill Jan 23 '12 at 18:06
8  
@DJClayworth That is not entirely accurate: sometimes trying to use a debugger is a poor choice, even if you have a good debugger at your disposal: you end up wasting a lot of time without accomplishing much. One case that immediately comes to my mind is solving concurrency issues; the other ones are debugging recursive algorithms with high branching factors, some dynamic programming algorithms, and hardware interrupt service routines. Of course it is silly not to use a debugger when you genuinely need one, but deciding when you start needing a debugger is a highly individual choice. –  dasblinkenlight Jan 23 '12 at 20:23
7  
+1 although I find a debugger invaluable for certain types of bug (particularly in more complex algorithms) there really is no substitute for a simply having a good understanding of the code –  Chris Browne Jan 23 '12 at 20:44
5  
@DJClayworth I deliberately went for a stronger statement than "a few occasions when not using a debugger is better": my brief encounter with competitive programming taught me that instinctively reaching for a debugger is not the most efficient behavior for me. These days I start by (1) quickly re-reading the code, and (2) examining the debug trace (when available) before (3) going for a debugger. In many cases, the third step is unnecessary, because I spot the problem in steps (1) or (2), write a unit test that reproduces the issue, and code a fix, all without using a debugger. –  dasblinkenlight Jan 23 '12 at 20:51
8  
I think what you really mean is that a programmer should have a debugging sequence, instead of clicking the magic "find bug" button. A debugger is an extremely powerful tool, but you don't fire up the chainsaw to trim the hedges. –  Spencer Rathbun Jan 23 '12 at 21:29

What a bunch of nonsense: "Real Programmers don't need Debuggers." Might as well say that a real programmer doesn't need any IDE, just give me a note pad and a dull pencil. The debugger is a tool like any other that aids productivity.

Also, consider that not everyone tasked with debugging code is familiar with that code in question. Many time contractors come into an environment where they only have a general ideal what is happening. They may even be given a detailed description of an environment – or a 20 year old schema map and guide to arcane naming conventions (try understanding the difference between table X1234 and table X4312 with fields F1, F2, and F3 [yes, garbage like this exists] when you are new), but many times that description is wrong; otherwise, why is there a "mystery" error.

As someone new to an environment, you can spend hours or days mapping and getting to "know" a large database for a problem area that you may fix and then never have need to look at again. This is a huge waste of time and money. If you have access to the debugger, you look see what is happening, correct it, and are gone in a matter of minutes. All of this "you don't need debuggers" hooey is just elitist puffery.

share|improve this answer
2  
this straw man rant doesn't answer the question asked, nowhere there is a statement "Real Programmers don't need Debuggers" –  gnat Nov 14 '13 at 14:10

Debugging is a very useful tools for inspecting the state of the objects and variables in your code at run time.

As previously mentioned in the answers above, debugging is extremely helpful, but there are some cases where it is limited.

In my experience, I find using the debugger to be very useful because it helps to reveal false assumptions that I was making about the state of my code. Some people aren't as astute at reading through the code to find a bug, so debugging can help in revealing false assumptions that you or another developer made about the state of the code.

Maybe you expect that a parameter will never be null when passed to a method, so you never check for that case and carry on in the method as if that parameter will never be null. The reality is that parameter will end up being null at some point even if you set as a pre-condition to the method that the parameter should never be null. It always will happen.

In contrast to debuggers' usefulness in the aforementioned examples, I find it difficult and somewhat not useful to use when multi-threading (i.e., concurrency, asynchronous processing) is involved. It can help, but it is easy to lose your orientation in the multi-threaded fog when the debugger's breakpoints are being hit in one thread at point A and a completely separate thread at point B. The developer is forced to push the new breakpoint "thought process" on the top of his brain's "stack" and orient himself to the code at the point of the new breakpoint. After the relevancy of breakpoint B decreases, the developer then switches back to the first breakpoint, and has to recall what he/she was looking out for before the trigger of breakpoint B. I know that this may be a confusing explanation, but my point in this paragraph is that debugging where concurrency is used can be a very A.D.D. (Attention Deficit Disorder) process, and so it may be more difficult to remain productive in your debugging thought pattern.

Also the unpredictability of concurrent code can further distract the developer in debugging concurrent code.

In conclusion, in my honest opinion:

  • Debugging when concurrency is used = increased tendency to lose focus of "debugging thought pattern"

and

  • anytime else = increased debugging productivity b/c your attention isn't interrupted by unexpected breakpoints (unexpected due to race conditions).
share|improve this answer
2  
+1 for bringing up the issue of debugging in concurrent environments, where the usefulness of traditional debuggers often diminishes to near zero. –  dasblinkenlight Jan 23 '12 at 19:27

If the bug occurs in a client's computer, or in a computer that its environoment is much different than yours, then setting up a debugger / remote debugger is cumbersome. So, for the cold day where you get a bug from the field, the response of 'but ... i don't have a debugger' doesn't help. Therefore, you need to develop a skill set of trouble shooting and finding the bug just through understanding of code and log files.

share|improve this answer

I'm surprised that the discussion on this topic has not mentioned "unit testing".

Because I do test-driven development, I don't spend a lot of time in the debugger. 10 years ago, I used to dutifully step through the debugger:

  1. After writing a piece of code to ensure that it worked and
  2. When I received a bug report to try to diagnose the problem

What I've found after 10 years of test-driven development is that I'm a lot more productive as a programmer if:

  1. I write unit tests before I write the code to ensure that I wrote it correctly
  2. I write unit tests immediately upon receiving a bug report to attempt to duplicate and drill-down on the problem.

Allowing the computer to run through the code and validate the result is thousands of times faster than I can think or step through the code to mentally validate the results, and doesn't make mistakes.

I still have to step through in the debugger occasionally, and I'm still engaged in mentally analyzing the code... but only rarely, and mostly for very tricky code.

share|improve this answer

Depends on the scope of a problem. If the program is small and things are well-divided you probably can figure it out by looking. If the program is 4.5 million lines of code developed by a team of 100+ people over the course of several years then certain bugs will be impossible to spot.

The one in question in said program (in C) was a memory overwrite. The debugger with a memory breakpoint identified the offending line of code as soon as the bug appeared. But in this case there is no way someone could have read and retained all 4.5 million lines of code to identify the one spot someone wrote past their array (plus they'd have to have known the runtime layout of the memory for the gargantuan program's state about 10 minutes into a long run of inputs to get it to that point).

Point being: In small programs or things that are highly modularized you can get away w/o a debugger. If the program is really big and complex then the debugger can save you lots of time. As others have said, it's a tool, and it has its situations where it excels above any other method, and others where it isn't the best choice.

share|improve this answer

With good unit tests, and exceptions that provides you the backtrace, you rarely have to use a debugger.

The last time I used a debugged was when I got a core file in some legacy application.

Am I being a "debbuger minion" or are these guys being "too hardcore"?

Neither. They are just kind of people who likes to make their life harder then it should be.

share|improve this answer

Personally, I try to minimize the use of a debugger by:

  • using static checkers and similar compiler options which hint at possible sources of bugs just by analyzing the code
  • writing code with as few side effects as possible, in the most functional style possible, eliminating mutable state where possible
  • writing unit tests with the minimal reasonable granularity
  • not swallowing exceptions

Of course, everyone makes errors, so even when composing programs this way, if a test fails, I use the debugger to inspect a value of an intermediate expression. But by adhering to the above principles, the defect is easier to locate, and debugging doesn't mean a painful, indeterministic process.

share|improve this answer

I read an argument against debugger debugging here recently (or was it StackOverflow?). You should have test cases against your code. If your tests pass, your debugging probably isn't going to exercise the bug (assumption: you will debug with data similar to your test data).

On the other hand, logging is mandatory. If you pass your tests and deploy to production, you may find that you have a bug. The evidence of the bug is from something that happened in the past. i.e. someone says, "How did that get in there?" If you don't have good logs, you'll never find the cause. Even a debugger may be of no use at that point because you don't know what the data looked like that actually exercised the bug. You need to be able to debug the application from the logs.

Unfortunately, I'm paraphrasing quite a bit, and may be doing the original argument a disservice. In particular, the position of "There are important debugging aides to spend development time supporting" might be orthogonal to the importance of debuggers. But the part about the difficulty in setting system state in a configuration that makes debugging useful for finding bugs struck me as something to think about.

share|improve this answer

Debugging is just a tool that a good developer should use proficiently.

Certainly sometimes you can know by heart where the bug can be if you know the code base. But you can also lose an entire day or week to find a pesky bug just by looking into the code.

In dynamically typed languages without some kind of debugging (even if it's just dumping values to the console) guessing sometimes becomes impossible.

So to answer your question - maybe they are brilliant programmers, but their troubleshooting skills and their proficiency when hunting bugs are bad.

share|improve this answer

Many answers, but not a mention about Heisenbug?!?!

Heisenbugs occur because common attempts to debug a program, such as inserting output statements or running it in a debugger, usually modify the code, change the memory addresses of variables and the timing of its execution.

I use debugger, only in the worst case (for hard-to-find bugs). Also, as per best practices that many acclaimed developers/testers have been talking about, it's good to unit test the code thoroughly. That way, you can cover most of the problems and hence there would be no need to use the debugger.

share|improve this answer

There is a difference between not needing to use a debugger and not knowing how to (or refusing to) use a debugger. The debugger is just one of many tools to use in tracking and fixing bugs. I've worked with developers who can puzzle it out in their head and others who think they can.

The best mix is to write your code so it is easy to test via unit tests, and logs the errors. Then you hope you don't need to look at the logs or use the debugger. It is kind of like buying insurance. You hopefully never need to use it, but once you run into a bug that can't be solved by rechecking the code then it is too late to add proper error handling / logging, unit tests, or learn to use a debugger.

Different tools/platforms favor different debugging techniques (debugger, logging, unit tests, etc.) As long as a developers is familiar with a few of the techniques for their platform/tool, in addition between just rechecking the code, then they may be a skilled developer, but if they only have one trick when it comes to debugging then they will eventually run into a bug they cannot find or fix.

share|improve this answer

Erm, it depends on the person. Personally, I don't use debuggers that much myself. When I program micro controllers, I basically use LEDs or writing data to EEPROMs to "debug" the code on it. I don't use JTAG.

When I program software for PCs or servers, I tend to use logging and lots of console output. For C-style languages, I use preprocessor directives, and in Java I used log levels.

Since I don't use debuggers, would you say I'm doing something wrong? It's the editors jobs, to show me where I have syntactical errors, and when there's a logical error, I just have to run tests.

share|improve this answer

Your best guide to the practice of debugging is Steve McConnel's book Code Complete. Chapter 23 covers debugging in detail, and I will distill a few points from it.

  1. Understanding the problem is important, and use of the debugger is not a substitute for it.
  2. Guessing is a bad approach to debugging. If your colleagues are really using guesswork, rather than thinking about the problem, then they are doing a bad job. Guesswork means sticking random print statements in the code and hoping to find something useful.
  3. If your colleagues genuinely don't know how to use a debugger (rather than choosing not to use one) then yes, they are incompetent, just like someone who doesn't know the syntax of the language they are supposed to be using.
share|improve this answer
1  
Whilst I agree with you on most of your post, I think incompetent is unfair. It's possible to develop without the use of a debugger, it's just inefficient. Some people learn about debuggers before others! –  ChrisFletcher Jan 23 '12 at 21:49
2  
@MikeDunlavey Does that person know how to use a debugger and choose not to use it? Fine. If they don't know, then I stand by my statement. –  DJClayworth Jan 24 '12 at 16:52
1  
Stand as you like, a time could easily come when that adjective might be applied to you. Then you'll understand - it's schoolyard stuff. –  Mike Dunlavey Jan 24 '12 at 19:42

Hate to generalize, but many programmers I have met think there is only one way to solve a problem (their way). It is easy to assume that every possible test has been thought of. A different perspective can be very valuable.

Programming by trial and error can come up with some great new approaches, and catch things others have missed.

The downside, usually takes much longer.

share|improve this answer

Use the debugger whenever possible. The debugger will either simply nail the issue (oh look, we didn't check for this value), or provide a great deal of context that is useful when analyzing the relevant code (wow, the stack is totally messed up, I'll be it's a buffer overflow issue).

share|improve this answer

The more I know a code base, the less I need a debugger (but I'd still check the reported error, it is an important clue in any reasoning).

It is a fine tool to understand some dynamic behavior of small to medium complexity, but I often find out that it focus me on the details instead of the bigger picture. And after a while, that's where the problems are: in wider scope interactions whose dynamic behavior tend to be more easily understandable with other tools (logging of input and outputs at module boundaries for instance).

share|improve this answer

They may not be bad programmers, but they are probably terribly inefficient troubleshooters.

I tend to follow the advice from Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems (David Agans), and this one falls squarely under the guidance of "Quit thinking and look"

share|improve this answer
12  
I disagree, though I won't downvote. As delnan says, if you can understand what the code is doing, it can be faster to spot what it is doing wrong than to step through the debugger and try to find when it goes wrong. That said, a developer who refuses to use a debugger when they can't identify the problem from reading the code is making a big mistake. –  Mark Bannister Jan 23 '12 at 19:14
10  
@Mark Bannister - I see what you are saying. Let me amend that to, if you have been looking for the problem in code for more than 15 minutes, give up and use the debugger and don't be stubborn. –  JohnFx Jan 23 '12 at 19:35
9  
I think a good programmer should not be dependent on the debugger. This should not keep him from using one immediately (where available), once his insight fails -- or periodically, to make sure his insight is still on track... –  comingstorm Jan 23 '12 at 23:41

Any job requires using the right tools the right way. If you have a debugger then use it to see what is actually happening. Most bugs are caused by assumptions.

I've worked with developers who refuse to use debuggers because they knew better. The classic response I got once was 'the crash isn't being caused by me, I spent all day inspecting the code [where it was crashing] and there's nothing wrong'. (What about that null value that was read in from the db?) The boss seemed to think it was a great reply but the customer didn't.

I got off that team as fast as I could. Their purpose was to featherbed the job and make a simple 10 minute problem into an all-day-looking-busy problem.

share|improve this answer
17  
+1 "Most bugs are caused by assumptions" are very wise words –  ZJR Jan 23 '12 at 16:19
14  
I assume all bugs are caused by assumptions. (See what I did there? =P ) –  dan_waterworth Jan 23 '12 at 16:36
3  
@ZJR: Which is why assert is so great. Check your assumptions. Check them often. –  Zan Lynx Jan 24 '12 at 17:19

Hard to tell. Debugging by guessing might work if you already have an idea about what the bug is (incorrect value passed to a library function, possibly invalid SQL, etc). I admit I do it sometimes when the error itself seems small or obvious, such as "character buffer too small" - the stack trace shows me the line it failed and I don't need a debugger to solve that one.

Doing this all the time can be counterproductive and if the first few "guesses" fail, guessing is probably the wrong problem-solving strategy and a real debugger should be called in. Normally, I'd say there's absolutely nothing wrong with using the debugger.

That being said, I've worked with tools and environments where the debugger was so difficult to get working right, or so minimal and useless that guessing was unfortunately often a better approach. I've worked with some proprietary tools that didn't even have proper debuggers. I suppose it's possible that if a person worked in such environments too long they'd eventually lose their trust in debuggers and rely soley on the guessing approach.

share|improve this answer

I Think they're being a bit too hardcore. Personally when I run into a bug, I recheck the code, try to trace it in my mind from the program logic, because that sometimes helps me uncover other problems or side effects easier than just using the debbuger and fixing the bug where it manifests itself.

Even when I think I've nailed it, I usually debug it to make sure I'm right. When the problem is a bit more complex, I believe debugging is absolutely essential.

Also... just my opinion but, there is no excuse for not taking a decent advantage of the tools a modern IDE can bring to the table. If it helps you complete your job faster and in a more reliable way, you should use it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.