New & Revolutionary Debugging Techniques?
An anonymous reader writes "It seems that people are still using print statements to debug programs (Brian Kernighan does!).
Besides the ol' traditional debugger, do you know any new debugger that has a revolutionary way to help us inspect the data? (don't answer it with ddd, or any other debugger that got fancy data display), what I mean is a new revolutionary way. I have only found one answer.
It seems that Relative Debugging is quite neat and cool."
You get what's called 'glassnose syndrome' too easily.
Instead concentrate on building software in many small incremental steps so that problems are caught quickly, and on separation of design so that dependencies are rare.
If you can't find a problem, leave it and do something else.
Otherwise, print statements, yes, that's about the right level to debug at.
Ceci n'est pas une signature
I haven't used a debugger in years; print statements are the only debugging tool I need.
But bear in mind that almost all of my work these days are in environments where the bugs that traditional debuggers help you find are pretty much impossible to make in the first place (Python, Java, etc.). Instead of tracing data structures through bits of memory and navigating stack frames, you just focus on the application itself. It's kind of refreshing.
Debugging backwards in time. See the Omniscient Debugger for an implementation in Java. Instead of re-executing the program a thousand times, each time setting breakpoints and watchpoints in different places to get nearer to the root cause of the problem, this debugger completely records all key events and lets you view the complete program state at any point in time.
Donate free food here
Basically, you can define an aspect to capture points in your program that are of particular note, and then do debug handling at those points. Aspect oriented programming allows you to break out that debug-handling logic into seperate modules, keeping your main sourcecode nice and clean.
Aspect-oriented programming (AOP) has a lot of other uses too. I think in 5 years or so talking about AOP will be as commonplace as talking about OOP. They are orthogonal concepts.
Cheers, Me
The fundamental issue here is that people are ALWAYS looking for a way to avoid having to write unit tests. I'm happy with a combination of Intellij and print statements. So far I've never had a situation where I though "the debugger isn't giving me enough information."
I think that one of the reasons I'm happy with the debugging options available to me, is that I write my code so that it can be easily followed in the debugger. That means splitting my declarations and assignments, and other such things that make my code a bit more verbose, but eminently more readable. Lord knows as a child, I loved those complicated boolean switches, and cramming as much line into one line of code as possible. Now that my code is maintained by more people than me, I'm tired of people having ot ask me "what does this do." I used to get angry at them, but now I get angry at myself when that happens. We don't just write code for the users, we write it for our peers. Write code that your sibling developers will be able to follow in a debugger. I know some code is hard to follow, even with a debugger, so I write all my conditions as clearly as possible, name my methods and variables as clearly as I can and refactor reusable code into well named "submethods", so that we can solve "modules".
This is because I want my code to last beyond my employment. Therefore it has to be maintainable by someone other than me. The real test of your code is: can someone ELSE debug it, using whatever the heck tools they want. A fancy debugger is a fine thing, but someday someone is going to have to debug your code with inadequate tools. My rule of them is "Code as if your life depended on someone else being able to fix it"
Nothing great was ever achieved without enthusiasm
They might not be revolutionary, but the is a few ideas
which can be just to reduce the number of bugs in a program.
1) 100% unit test coverage of your programs.
2) Statistical Debugging
3) Valgrind
4) The D programing Language
with build in support for unit testing, contracts and class Invariants.
Donate free food here
- The best programmer I've met once told me that once you've dropped into the debugger, you've lost, which over time I've found to be quite true. The best debugging practice is to learn how not to use a debugger. (e.g., Are you using threads when they're not absolutely required? Say hello to debugging hell...)
- When you must debug, print statements cover 97% of the cases perfectly. They allow you to formulate a hypothesis and test it experimentally as efficiently as possible.
- Differential debugging is a nifty idea, but most of the time it'd be better to just use it with your print statements as above (e.g., print to logs and then diff them). For the one time per year (or five or ten years?) that having a true differential debugger might pay off, it's probably a loss anyway because of the cost and learning curve of the tool. (I thought about adding this to SUBTERFUGUE, but realized that no one would likely ever productively use this feature.)
- If you need another reason to avoid this tool in particular, these guys have a (software) patent on it. Blech!
--Mike"Not an actor, but he plays one on TV."
Its all very well talking about elegance and planning in advance until you try and deal with hardware. No amount of zen contemplation of your code is going to tell you what a debugger does about how the hardware and its documentation relate.
The neatest debugging tricks I've seen so far are those logging all inputs and returns from the OS level. Since you can replay them you can rerun the app to an earlier point and investigate - in effect you can run it backwards from a bug to see how it got there.
"Always code as if the person who ends up maintaining your code will be a violent psychopath who knows where you live." -- Martin Golding
"Seek first to understand." - Socrates