Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I never noticed until now, but I never use a debugger either. An employer urged me to start using one while I was working on their code, but it's just not natural for me. If I need to debug a crash, I just print the 1-2 variables of the state involved, see what's wrong, and fix it.

Is there anyone who uses a debugger for more than inspecting state?

EDIT: I guess lower level languages and more involved applications use debuggers much more extensively.



Debugging compilers: there may be over 1GB of heap (so you can't reasonably dump / log everything), with promiscuous pointers connecting dense blobs of data (one or two variables don't cut it, you need on the order of 1000s); and the code is 20+ years old, and the people who originally wrote it have long since moved on - nobody knows all the code.

One example. Sometimes what you want is a time machine: figuring out how a particular variable reached its value. So you swap out the Windows memory allocator (which randomizes initial heap addresses) for one with predictable addresses, run the program until you find the dodgy value, take its address, then restart the program with a hardware breakpoint setup to monitor and log the stack whenever modifications are made to that memory address.

This kind of "backward tracking" takes no more than 5 minutes on a project that's set up for it (i.e. with the appropriate allocator available and switchable). Solving the problem by guessing locations, dropping printfs in the code, etc. is rather less productive.

Other uses: debugging code you don't have the source for, OS code, binary compatibility issues etc.

(Crash bugs are usually not a big deal; usually, when the code crashes, the crash location is relevant. Bugs that corrupt state are much worse (heap corruption, races / concurrent modification, etc.). The original bug resulting in the final bad behaviour may be completely different from where it appears.)


Aren't there debuggers that step backwards? That sounds useful in many cases, and not impossible to create, at least for special cases.


Yes, they're usually called "Omniscient Debuggers". Intellitrace on Visual Studio provides this kind of funcionality.


Also GDB has supported reverse-execution on some environments (i386-linux and amd64-linux included) since version 7.


Some debuggers let you "drop frames". This brings you back up the call stack and you can step back down into the beginning of the method call.

http://stackoverflow.com/questions/2367816/when-using-the-ja...


OCamlDebug does this. Magic :-)


Umm...

  * Tracing code execution paths to load the code into your mind
  * Modifying state inline so you get a different path without re-running
  * Modifying state like FirstName to trace just how the bugger gets into the output
  * Some sophisticated debuggers like java can allow you change code, then hot recompile and deploy code LIVE.
  * Suspend threads when you reach a breakpoint so you can dig around at all the multi-threaded state at that point
     - Although multi-threaded debugging is where printfs shine
All of that is much more difficult with just printfs.


Sometimes the logging is not enough, and you cannot isolate the case to prepare appropriate unit test.

Just few days ago I had a strange problem with the order of imports in Python at the border of my code and external library (Celery). There were import hooks involved but they didn't seem to be executed properly in certain conditions. I could reproduce them quite reliably but I needed to pinpoint the exact import (inside Celery itself, mind you) that was causing the problem. pdb (Python debugger) was indispensable while solving it.

On the other hand, though, it was probably the first time in many months that I used pdb for more than 5 minutes, and for something more complicated than checking why a particular test fails.


I agree, you certainly have to trace execution flow somehow, and a debugger is the best way to do that. However, my realization was more that the debugger wasn't useful for the vast majority of cases. Until now, I somehow thought I used a debugger a lot, and that it was a big part of my debugging (after all, how do you debug without a debugger?).

This post made me realize that 95% of the time I fix errors from just the stack trace, 4.9% from logging, and 0.1% from actually debugging.


Thats my experience as well - I rarely use a debugger, but when I do I cannot imagine any other way of finding out what is going on.


I don't know about the nature of the problem you were working on but in my experience there are some cases where the problem is far too complicated to be fixed with debug print statements. I couldn't live without my debugger.


For example, when debugging operating system code running before printf (or printk) is available. I barely used debuggers on high level code, but in low level its an all different story.


I can say the same for high level code, but I use debuggers when the source code is not available or I'm coding a device driver or something in assembly.


Yes, I've done that sort of programming (embedded stuff) and debuggers and other exotic tools are very useful.


For my own code, not so much. For resolving problems or understanding complex control flow in someone else's code, more frequently.


I use a debugger. If you've got some input that gets transformed into unexpected output, it's great to follow the code along. Of course, placing debug output works too, be the debugger is usually faster in this situation.

It's good for white box testing. It's also good for compiled languages. You know something is wrong, but you don't know why it's wrong.


I often feel that comfort with debugging procedures is what separates an awesome developer from a codemonkey. I've long wanted to find a good way to teach debugging concepts to people. It often makes the difference between being prolific and being competent, in my opinion.

...just based on years of observation




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: