Debuggers are evil

Thread Starter

someonesdad

Joined Jul 7, 2009
1,583
In the middle 1990's, I took a full-time 4 month software class at work. One of the lessons from the course was "debuggers are evil". I have come to understand this statement at the level the instructor meant it and I thought I'd share the thinking, as I think it's important.

The message the instructor was trying to get across was to design your code carefully and think it through carefully. Use careful code reviews (your own and with others' help) to find bugs. You have to learn how to think like the computer -- this takes a lot of practice. However, you'd be amazed at how many problems can be found by this method.

The instructor graded all homework code (a typical set of homework problems could result in 20-30 pages of C code and prose) by simply reading the code and finding the students' bugs. I suspect many of the students in the class (there were 10 of us) didn't realize what an important lesson they were seeing by this behavior. I don't recall the instructor ever being wrong. And this wasn't beginning programming, but stuff using sockets, IPC, GUI stuff, assembly, complicated data structures, etc.

Too many people throw their code together and then run it, expecting to find the bugs with a debugger when the bugs show up. This is a fundamentally-flawed approach, as it means you haven't thought carefully enough about the program's design. But it's the road most of us take, because it's the "easiest" in the sense of getting something working in the quickest way.

The reason why debuggers are evil is because they will all fail you sooner or later. Beginners doubt this, but I have seen EVERY debugger I have used fail me in some way. A little reflection tells you they're programs like any other and they can have bugs. I experienced this failure first-hand in the class when a UNIX debugger failed to work correctly with UNIX signals that were critical to my program. I had to resort to printf's to see what was going wrong.

The process of learning to design, develop, and implement code without a debugger usually involves working with some kind of logging. We did all our work in C, so this was printf stuff to the console. We also learned of a variety of ways to turn logging/debugging on and off, such as signals, other IPC tools, trigger files, command line switches, a socket connection, etc. All these methods can prove useful at some time. Use your creativity to think of more of them.

I remember working with a couple of engineers once on a problem in one of the main products of the company (most of you have probably worked with one of these products, as it's a well-known tradename). It was in the boot code of the product and this code was pretty complicated. We didn't even have the luxury of having a printf function, as it was an embedded device with no concept of a console. The senior engineer eventually figured out the problem using experience and reading the code. This involved days of work by a number of us, burning PROMS, testing, etc. This kind of stuff DOES happen in industry, so the teacher's training was valuable and vindicated.

I'd like to comment on an area where I think debuggers are valuable and should be used. In McConnell's "Code Complete", he talks about the value of having a programmer step through his code, watching how things change and how it responds to the program's inputs. This is quite valuable and will be used by knowledgeable programmers to both validate their thinking and cause exceptional conditions to be generated, causing seldom-executed chunks of code to be exercised. But it can be time-consuming to examine lots of code this way. Thus, it's not often done, at least in my experience. Also, for embedded systems, it may be next to impossible to figure out something without an emulator or debugger. This is fine, as these are specialized conditions.

I think a better technique, in general, is to spend time writing test cases for the software, at least where it's possible. This is very useful where you're writing library code, but harder to use when e.g. you're working on a GUI (without a fancy automated testing facility). The code reviews spend equal time examining the test cases to ensure that they are getting the proper coverage. The beauty of these tests is that they can be executed every build; this catches changes that break existing functionality (and explains why they are called regression tests). In the last project I worked on, I wrote the build/test environment to run the thousands of regression tests we had and email both the project manager and responsible engineer with the failure information. This was wonderful for some "negative" visibility and ensured that the engineers tested their changes carefully before merging their code to the main branch. Most importantly, it was timely (we found out about the problem in less than 24 hours from the change).

The instructor's deep, fundamental message was that most bugs can be found by careful code review. I've seen this validated many, many times. An even deeper message was to learn how to design code so that the bugs aren't there in the first place. This distinguishes the real software engineers from mere programmers. A software engineer knows how to design; a programmer just knows the syntax of the programming language in use.

Truthfully, I have to admit that I often don't consider myself acting at the software engineer level, as it's sometime too easy to fall back into the "programmer" mode.
 
Last edited:
Hardware Debuggers & Emulators are a tool, use them properly and they can save you a headache or two.
Simulators are real hit & miss. They're a software representation of a bit o hardware. They can help but I would never rely on them.
 

retched

Joined Dec 5, 2009
5,207
Awww Yuo guys are crazy! The spll checker I wrote and use passed the debugger perfecytly. It simulated great. I didn't even have two bother testing. Went strit to product!
 
Top