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.

I just wonder what is the biggest trouble developers encounter when debugging? I can think of three answers but I am not sure whether they are correct:

  1. Trouble in locating the bug? But most of the times the crash stack traces can provide enough info in locating the bug.
  2. Trouble in figuring out the reason and fixing the bug? But if you can locate the bug, then probably you got the rough idea of how to fix it.
  3. Trouble in applying the fix? Probably, some tricky bugs force developers to make changes in a lot of places, thus breaking the structure/design of the original program. But I'm not sure whether this is a trouble.

This question may be too general, but I'll be happy if I can get some feedbacks from you guys. Also, if you have other troubles in debugging please point out. Thank you a lot!

share|improve this question

migrated from stackoverflow.com Mar 24 '11 at 6:28

This question came from our site for professional and enthusiast programmers.

2  
as long as you can debug, the trouble is much smaller –  tactoth Mar 24 '11 at 7:56
3  
The stack trace only tells you where the program crashed. The bug is often nowhere near where the program crashed. –  David Conrad Mar 24 '11 at 11:17
    
Others have mentioned this too, but #4: regression issues. In other words, fixing 1 bug creates 2 others. And since you've already "tested and verified" that part of the code, those 2 new bugs slip by. Basically, you have test everything everytime, and no one wants to do that. –  barrycarter Mar 24 '11 at 15:04
    
@David Conrad: and that's if it ever crashed, most bugs are more about getting back wrong answers to your questions that about making the software crash. –  Matthieu M. Apr 8 '11 at 18:28
add comment

13 Answers

up vote 20 down vote accepted

Usually the actual fixing of the bug is the simplest part. The main problems I tend to have are these:

  1. Getting an accurate bug report

    Most bugs are not crash bugs, and users are notoriously unreliable when it comes to reporting exactly what the bug is.

  2. Knowing what the real behavior should be

    I often get bug reports when the software behaves as-designed, because users don't understand the concepts. You could chalk it up to bad UI design, but some business processes just are complex. I also get bug reports where it's easy to say something is wrong (e.g. nonsensical interaction between various rights protecting a resource), but very difficult to say what the correct behavior should be.

  3. Knowing the impact down the line

    When you build software that has a lot of custom development done on top of it, it becomes very difficult to guess what impact a change could have.

share|improve this answer
    
+1 for accurate bug report. I think that could be generalized to most problems in computer science - inaccurate problem description, e.g. the customer describing what they want to happen, when that's not it at all; someone describing what language features they want to use, rather than the algorithm they need... –  Wayne Werner Mar 24 '11 at 9:56
add comment

Reproducing a bug that rarely happens. Especially when coping with multithreading.

share|improve this answer
3  
Only thing that seems to work in that situation is extensive logging. –  Thomas Stock Mar 24 '11 at 7:50
3  
Multithreading + sockets == hardest bugs to pin down. This answer made me flinch just reading it, so I had to +1 –  Wayne Werner Mar 24 '11 at 9:43
8  
@Thomas: yes. Unless that logging introduces changes that make the bug go away. Very, very awkward. –  stijn Mar 24 '11 at 11:01
3  
Or, only happens in release mode with no debugger attached :-) –  CodeNaked Mar 24 '11 at 11:42
2  
That single request failing at 13:37 of every third thursday of leap years, only if it's windy in Bangkok, only if exactly 3456 clients are connected, and only if everybody is wearing matching colors. Yeah, I know what it feels like. –  Agos Mar 24 '11 at 12:38
show 2 more comments

Spaghetti code

Even if you locate the bug, it's hard to understand how the fix will affect the code.

EDIT:

The trouble is in the nature of the bug.

Solving any of these bugs seems to be hard: Unusual software bug.

  1. Bohrbug
  2. Mandelbug
  3. Heisenbug
  4. Schrödinbug
  5. Phase of the Moon bug
  6. Statistical bug
  7. Alpha particle bug
share|improve this answer
1  
Further argument for Boy Scout coding –  Wayne Werner Mar 24 '11 at 9:51
add comment

The worst thing with a traditional debugging aproach for the unsafe languages is that symptoms of a problem are often spotted somewhere far from its origin. E.g., if you've got an out-of-bounds array access somewhere, you might encounter a segfault in a totally unrelated part of a code.

For the same reason, bugs may behave differently in a debug and release build.

share|improve this answer
add comment

I would say #1 is probably the worst, when the stack trace doesn't give you enough information. The problem could be a race condition, memory corruption that happened a few million instructions ago, whatever.

It's also particularly difficult to locate a bug when there is an external system involved (e.g. the operating system) - see here for an example*.

* Disclaimer: I'm not saying the operating system is at fault, but it's much harder to troubleshoot this one when the external system's implementation is hidden.

share|improve this answer
    
Right now, I've got a bug where I know exactly what happened at the crash. The problem is that it's due to a bad condition in a very large data structure that is constructed earlier in the processing. Or another crash where the call stack tells me that x was zero in the construct if (x != 0) { ... no reference to x ... x->DoSomething(); ... }. –  David Thornley Apr 8 '11 at 14:19
add comment

Trouble in locating the bug?

This can be tricky in cases when the effect of the bug is not immediate. Examples others have mentioned are hard to reproduce bugs such as concurrency issues. Further examples are memory leaks, memory/resource corruption.

In case of concurrency problems, one can't even use a debugger, as such bugs usually depend on subtle timing coincidences, and stopping the execution usually breaks these.

Trouble in figuring out the reason and fixing the bug?

In the above cases, finding the real root cause can be extremely difficult.

Trouble in applying the fix?

As already mentioned, a lot depends on the quality of the code. Moreo critical factors are the presence/absence of tests, and the level of understanding about what the code is actually supposed to do.

Without tests and/or a solid understanding of the effect of changes to a particular piece of code, it can be extremely risky and scary to make any changes in a complex program.

Just recently, I had such a bug in our legacy project, where even clarifying with business whether this was actually a bug or a feature took several weeks. (Luckily, the bug itself was easy to fix by removing a single line of code - but as it resided in the middle of a complex class, I had to write a lot of unit tests to ensure I'm not breaking anything.)

share|improve this answer
add comment

Incomprehensible source. A lot of undocumtented special cases which you need to consider when deciding where to put the cut.

Some code is so bad that you hardly dare even touch it, but you still need to fix it. That is where deities come in...

share|improve this answer
add comment

Given that the code is not easy to read, I would say figuring out what the bug is all about due to the insufficient details and assumptions presented (which adds up to the confusion) by the one who encountered it.

share|improve this answer
add comment

Debugging in C++ often means getting the code to compile in the first case since the origin of the error is often non-obvious from the compiler message.

The worst compile-time debugging that I had to do involved an error message that – due to deeply nested templates – was several megabytes in size. Worse, the actual error location was not provided.

See, the GCC compiler truncates error traces that are too long. So let’s say that the compiler fails to instantiate a function template bar that is called from within foo which itself is called from within main. The compiler will output an instantiation trace (similar to a stack trace):

in file main.cpp line 40: in main(int, char**)
in file main.cpp line 20: in foo()
error: no matching function call to `bar' …

… something to that effect.

Now, what happened to me was that this trace was very deep (~ 20 functions) and the error was somewhere in the middle. But GCC left out that section: it only printed the topmost functions (main and a few levels deeper), and the bottom-most functions which were inside a library. The actual error was inside a function in between these functions in the call hierarchy. But GCC only told me “… skipping 5 functions …”.

So essentially I had no indication where the error was: neither in which function nor in which file. I ended up having to rewrite a huge portion of the project since I was unable to locate the error.

share|improve this answer
add comment

My current debugging troubles stem from a slightly buggy TFS and teammates that tend to do infrequent check-ins. The source control will drop a couple of random files and not update them recursively like it is supposed to. There are about 40 projects in the solution each with hundreds of classes, so this can get hairy. I'll do a get latest in the morning and have 1,200 errors to track down every time. It usually is just one or two missing files, but the errors are so numerous and often caused by weird hierarchy issues, so it can be quite a bear to manually track the files down. It hasn't been so bad though; it takes me much less time these days and I've learned a lot about tracking down those little errors that have huge consequences.

share|improve this answer
add comment

As a visual studio developer, I hate that LINQ is not supported in the immediate window. If you could use linq in the immediate window, you would more easily be able to examine your data.

share|improve this answer
add comment

Reproducing the problem in a controlled way.

Try until you find the clear steps to reproduce the defect then try to remove one step after another to find the minimal steps with which we can reproduce the defect. Otherwise some unnecessary steps which are there in steps to reproduce will make us to assume a lot and wastes time in debugging unrelated code.

share|improve this answer
    
Can you provide more detail to your answer. The page you skipped is relevant and should be read. –  ChrisF Apr 8 '11 at 14:42
    
Can you edit this into your answer. –  ChrisF Apr 13 '11 at 15:02
add comment

Closed Source

Since I am struggling with one such problem at the moment, I will add it to the list. Some of the most difficult debugging is when I don't have access to the source of something integral to the bug, due to contractual/licensing requirements or just plain logistical issues. I don't mean closed development tools or platforms here, or what license my code is released under, but whether I can view and change all the code that is directly in the bug's scope.

I am currently working on a client and effectively have no visibility into the server code. I am 99% sure the problem is on my side because my code is new and the server side has 5 years of field testing, but not being able to look at the server source to see exactly what responses are expected at which points, or change the server source to produce only the messages of interest, or increase timeouts in a debug build, makes things much more difficult.

share|improve this answer
add comment

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.