http://www.perlmonks.org?node_id=76174

Three times in the last week, while coaching people through some thorny debugging problem, I've found that their bag of debugging tricks didn't seem to include the old standby of writing code to sanity check data structures before the program goes kaBOOM. What I observed was that they tended to run their programs until things went boom, and would then poke around the wreckage in the debugger looking for clues. If this meant restarting in a debugger, they would put a breakpoint as close to the explosion as they could. Not a bad first approach, but if it is the only one you try (and you never look upstream), a lot of problems will remain elusive.

When I asked them "what's the earliest time you think the underlying problem might be occurring, and what's the simplest check you could put into the code to detect it sooner?" they all gave some variant of an "oh, wow, what a good idea" response.

These were all people with 2-4 years of experience.

So I'm wondering: Are the available of good debugging tools actually making us less capable of debugging by appearing to remove the need to think deeply? Have we moved out of our Pioneering phase, where individuals have to be resourceful to survive, and into a Settler phase, where people can usually rely on someone else to provide the debugging service for them, and then let those skills atrophy?

What are you seeing? Are "kids these days" more, or less capable debuggers? What's in your bag of debugging tricks that seems to be missing in others'?


Clarification: I'm not talking about the debugging skills (or debugging avoidance skills) that people apply to their own code. This question goes to the skills that need to be applied when working in a multi-100Kloc system.

Replies are listed 'Best First'.
Re: Are debugging skills atrophying?
by merlyn (Sage) on Apr 27, 2001 at 21:52 UTC
    Didn't we do a debugging thread here a while back? Might be worth it to check.

    In any event, I think the most important thing I learned in my 28 years of programming is "debugging is hard". So I spend nearly every moment of my time while I'm programming thinking about how not to put bugs in in the first place, or at least have a pretty good idea what I just broke on the last edit cycle.

    My methodology is basically:

    1. Start with an empty file.
    2. Write a dozen lines of code
    3. Run it
    4. If that doesn't work, add a few warn statements until I see what I broke, and fix it.
    5. Add another dozen lines of code. Repeat.
    The key seems to be small incremental progress. Note that this methodology works for command-line, CGI, and whatever. Always have a testable version that's no more than a dozen lines different from the one you're working on. Then you'll know your error is always within the last dozen lines of code you wrote.

    Another element is "understand what you type". You should be able to have a complete mental model of every step of what you type. Yeah, it sounds so basic, but I'm amazed when I watch my students copy random lines of code into their program and then say "it didn't work". When I ask them what a particular line does, they say "I don't know". Gosh, how do they expect it to work then!?

    So maybe the combined rule is "never type faster than you can understand". {grin}

    -- Randal L. Schwartz, Perl hacker

      I agree, every professor I've had for programming courses has told me to work on the smallest increment that I can find, and make sure it works and you understand it before going on.

      The problem that I've been struggling is that I have a hard time seeing the small parts, I want to see the whole right away. I've tried to fix this problem by working on small, generic functions (since taking a few OOP classes), and that's seemed to help me a lot. By working on the smaller functions, I tend to find bugs quickly.

      Arashi

      I'm sure Edison turned himself a lot of colors before he invented the lightbulb. - H.S.
        Well, if you can't see the small parts, work from top down first. I've often coded things as:
        my $data = get_data(); process_data($data); print_result();
        literally, as if it were pseudo code. Then I write stub routines, like:
        sub get_data { # returns scalar data pointer to my structure my $return_value; my $db = open_database($credentials); # must declare this above my $data = query_db($db, "select * from bar"); $return_value = massage_data($data); return $return_value; } sub open_database { my $cred = shift; warn "open_database doing nothing"; return undef; } ...
        and so on... Then at any time, I can "run" what I've got. And stay focussed on each area of development. If I need a class, I'll develop a generic class that I can plug in.

        Again, the goal is to type a dozen-ish lines of code, then invoke it. That's nearly always been possible.

        -- Randal L. Schwartz, Perl hacker

      We did have a debugging thread a while back, at Are debuggers good?, and both of us put it on our home nodes...
      Didn't we do a debugging thread here a while back? Might be worth it to check.

      You probably meant this one. :)

      Note that this methodology works for command-line, CGI, and whatever.

      ...except that it's a little bit more difficult in, for example, GUI programming. ie. It's not always easy to draw up a whole new form to test something out. For smaller, command-line and CGI's it should always be feasible to pull some piece aside though and examine it (I find Python's interactive prompt nice for this too.)

      Another element is "understand what you type".

      This does sound so basic, but I still forget this fairly often. :)

      So maybe the combined rule is "never type faster than you can understand". {grin}

      Agreed. Quality over speed is most often the right path to take, IMHO. Like the previous point cited though, this too may be oft forgotten.

      I'm amazed when I watch my students ...

      You're in an ideal position to have perspective on this, since you have a history of contact with students.

      What trends are you seeing in their approach to debugging?

        Well, for one, I deliberately don't waste time teaching the Perl debugger in the llama course (or in the llama book). Frankly, if you need to invoke a debugger on a 10-line program, you should not be a programmer.

        So, I see two kinds in the llama class. People who work like me, and people who don't. Most of the people who work like me (little snippets, until it works) get the job done quickly. Most of the people who don't seem to get into cut-n-paste frenzy, and then unable to continue with the later exercises where we talk more about concepts and show fewer working programs.

        I'm rethinking the strategy for the PROM course (packages references objects modules), simply because the "x" output from the Perl debugger is durn useful at just seeing what you autovivified. I have a "long" version of the course where I teach the debugger toward the end, but I've ended up demo-ing it in the middle instead far too often.

        Personally, my use of the debugger is limited to "perl -debug", to try out one line snippets interactively. I remember that neither Larry nor I had enough experience with the Perl debugger (even though he wrote it!) for the first Camel, and that's why there's very little on the debugger in there. Neither of us use it!

        -- Randal L. Schwartz, Perl hacker

        since you have a history of contact with students.
        I just realized that this statement taken out of context could send me up the river for a while.

        This morning, I found that amusing. {grin}

        -- Randal L. Schwartz, Perl hacker

        Always have a testable version that's no more than a dozen lines different from the one you're working on. Then you'll know your error is always within the last dozen lines of code you wrote.

      I read this and I think "shell script". Do you have a set of tools you use when youre programming? For example, the above procedure could easily be accomplished by something like this:

      #!/usr/local/bin/bash [ perl -c "$1" ] && cp "$1" "`echo $1| sed 's:.pl::g'`.bak.pl" && vim "$1"
      (forgive the shellness of the example, and I havent tested it either) -- but this would ensure that you have a working copy saved, that it is good, and you can continue to develop on the new copy. If you train yourself to pause every 12 lines, or (where i usually break) every new sub, you could save yourself a lot of time. I have a lot of scripts like this, I'm curious if you use anything like that.

      And yeah, you did recently post something on debugging, and I remember upvoting it. After looking in the Secret Search I see:

      I'm sure i'm missing stuff.

      brother dep.

      --
      Laziness, Impatience, Hubris, and Generosity.

        Yes you are missing something: an OS with a file access subsystem that automatically saves old versions of files for you. My friend you are missing the wonders of VMS :-)
Re: Are debugging skills atrophying?
by satchboost (Scribe) on Apr 27, 2001 at 21:28 UTC
    As I've never really worked very closely with debuggers, I've always worked on arriving at sane design and used print statements. It's been my experience that 99% of all problems that arise can be solved by one of these three methods:
    1) print statements. Usually, you are assuming that a given variable has a certain value when it doesn't. (Yes, I know that examining memory within a debugger does this, but I feel that debuggers are usually overkill.)
    2) Writing out the flow. You might be assuming that a function is called exactly n times, when it's really being called n+1 times. Or, that foo() is called before bar(). This contributes to sane design.
    3) Adding anal checks. Are you doing @$foo? It might be useful to verify that ref($foo) eq 'ARRAY'. These sound stupid, but if you're writing something that a human will enter data for, you cannot be too careful. If a human can mess it up, a human will mess it up.

    And, no, kids these days aren't less capable debuggers ... than we were when we were kids. I remember learning how to debug 8 years ago, when I was just getting into college. Just remember that a lot of the people with 2-4 years experience are only 19 or 20 years old. They're still kids.

Re: Are debugging skills atrophying?
by zigster (Hermit) on Apr 27, 2001 at 21:24 UTC
    This is certainly my experience. I have had quite an eye opening experience upon this subject. In recent times I have written java and TSQL. In both situations a debugger was not availible. At first I floundered and flapped ever time I hit a problem. Soon my old skill started to return. I started writting tighter code, with suitable debugging tools built within it. I used program by contract to ensure validity of data entering and exiting methods, I wrote validation methods as part of my objects to be called in times of problems, I wrote extensive debugging output toggleable at runtime. Now I am back in perl land (for a time) I have my debugger back but find I use it less as my code is tighter.

    Anything that does not kill your project makes you stronger
    --

    Zigster

Re: Are debugging skills atrophying?
by Sherlock (Deacon) on Apr 27, 2001 at 21:27 UTC
    Being rather new to writing Perl, I'm still learning some new debugging tools, but I have carried one practice over from my other programming languages that has greatly helped - printing the contents of my data structures.

    I tend to deal with rather compex data structures fairly often and it has lead me to become almost obsessed with seeing exactly what data I have stored in my structures - especially when I've found a bug. I've noticed that, all too often, fellow programmers simply assume that the data that's in their structures is correct and that their logic is wrong. They then spend countless hours trying to find the faulty logic only to find that their data was no good in the first place.

    My debugging rule of thumb is to make sure that you know exactly what you're dealing with and then you can step through your code with a debugger or even by hand, if need be. Without knowing if your data is correct in the first place, there's no way of truly debugging your code. I think this is something that programmers (sometimes very good programmers) take for granted and fail to inspect.

    Is that something that other people have noticed? I think that I might just feel this way because I deal with so many complex data structures.

    - Sherlock
Re: Are debugging skills atrophying?
by tinman (Curate) on Apr 27, 2001 at 21:30 UTC

    I tend to agree with you on your subject title.. I find that lots of people that I know, with significant development experience, know or do less than I do in terms of sanity checks...and I'm nowhere near perfect to begin with...

    Its too early in the day for a rant, at least where I live :o), but I'll say it anyway... there are too many people who never bother to dissect all the code that they write or use or actually try to understand the inner workings of their system... Many (*I shamefacedly admit I may belong to this category*) have fallen into the MFC ClassWizard trap, so to speak.. we trust that the code we write is never going to crash, or that it's going to run perfectly the first time...

    Sometimes though, its because of a genuine lack of time.. I've had to make conscious decisions to sacrifice complete robustness and error checking for getting the job done fast.. its an awful excuse, I know, but in the world that I work in, no one really seems to care how well I write the code or about what exceptions I handle, so long as it seems to work... rightly or wrongly, fostering that sort of attitude is bound to make people less conscious of the stability of their code, so long as you can push it out the door fast, then nothing else matters....

    I think also that what you speak of has its roots in your professionalism and approach to work... if you're writing something merely to do a job, then you take no pride in your work... and you try to do the minimum necessary....

    In my mind, the ultimate test happens when you have to extend/maintain/debug someone elses code... if anyone has to do that often enough, then these steps become automatic.. and that is only going to make a better programmer out of you...once stuff like writing readable code and appropriate error checks becomes automatic, then you have more time for the really cool stuff :o)

Re: Are debugging skills atrophying?
by virtualsue (Vicar) on Apr 28, 2001 at 14:21 UTC
    In my experience (20+ yrs) debugging skills can't be atrophying because so few programmers ever had them in the first place.
Re: Are debugging skills atrophying?
by chromatic (Archbishop) on Apr 30, 2001 at 01:07 UTC
    I write unit tests first. Since I know what the code must do, it's easy to write tests that will verify that it does exactly that.

    I'm not a good enough programmer yet that the code and the tests are always completely accurate with regards to what must be done, but if the test fails after I've written the code, I know something's definitely wrong.

    It's a lot faster, too, especially when adding a new feature.

    Chalk that up to debugging avoidance -- planning ahead and proving your code correct is how I reduce debugging time. (It's especially nice if you can whittle down the error to the last two lines of code you added.)

(redmist) Re: Are debugging skills atrophying?
by redmist (Deacon) on Apr 28, 2001 at 01:16 UTC

    This is where Laziness comes in. I have been too Lazy to learn the debugger, so I incorporate debugging code into my program itself. Who was it who said, "Never underestimate the power of print statements in debugging"?

    redmist
    Silicon Cowboy
      That's a good strategy when you're working on your own stuff, but I wager you'll need a bigger bag of tricks when working on a multi-100KLoc probject with over a dozen developers.

      At some point in every project I've ever been on, there's a BUG that wasn't foreseen or caught by careful iterative development and testing. Then the fun begins.

        Agreed. Greater amounts of code require greater tools.

        redmist
        Silicon Cowboy
Re: Are debugging skills atrophying?
by educated_foo (Vicar) on Oct 23, 2006 at 07:21 UTC
    Do you think this is something beyond just more, less-skilled, Java-only-trained students entering the workforce? My experience as a TA suggests that most CS majors only (barely!) understand languages very much like Java, are driven by an understandable-but-desperate desire for financial security, and program by trial-and-error.
      Which really gets down to saying that CS majors know little, if any, CS and are really novice programmers when they get their degree. Which means that the degree granting institutions are no longer places of higher learning, but are extensions of the vocational job training market. And, sadly, not always a very good extension of it. I have seen many CS majors who should have gone to vocational institutions or to a merlyn course, they would have learned more.

      A don't call myself a programmer, I am a scientist or engineer who programmes. I am sure as heck not a 'computer scientist'! But maybe a scientist who knows more about computers than many around him.

      Debugging is an essential part of writing programmes. But we didn't have a de-bugger in the days when we submitted Fortran-77 on decks of cards - so you did it by sitting down and pretending to be a compiler in your own head. Fortunately when I was introduced to assembly we had small monitors and debuggers that allowed for single stepping and a few other basic things.

      The Perl debugger is pretty scarey, but on a few ocassions it has helped me find and obscure stupidity in my code, but for the most part I find myself doing much as merlyn suggested in this thread, write little and test often. It is very esy to make pseudo-code in Perl and that sure helps structure the entire process.

      jdtoronto

        Yeah, I don't use the Perl debugger much myself, almost always finding a mixture of reasoning, "-w", and print statements more efficient. Better still, once you're proficient at this kind of debugging, you can apply it to any language that has "print" (i.e. almost everything but Haskell ;), no matter how poor its tool support.
        I have seen many CS majors who should have gone to vocational institutions or to a merlyn course, they would have learned more.
        I'm partly responsible for producing some of those, it shames me to admit... Sadly, as long as CS (programming, really...) is seen as lucrative, and a CS degree as one of its prerequisites, this is the way things will be. For whatever reason, vocational education is socially stigmatized here in the states.
Re: Are debugging skills atrophying?
by imp (Priest) on Oct 20, 2006 at 13:25 UTC
    I would agree that basic debugging skills are worse now than they were 10 years ago, but I would also say that basic math skills have deteriorated. Watch a group of friends try to determine what portion of a bill is theirs, and what size tip to leave and it is obvious. Blame the calculator.

    With debugging it isn't quite as simple though.

    When I first started programming I would sometimes write the program out on paper, and read through it while keeping track of all the variables. Being able to read code while keeping a mental list of what is happening is valuable when working in a group, but this skill is sometimes neglected due to the ability to run it in a debugger and watch certain variables.

    My ideal development strategy is as follows:

    1. Write the unit tests as a working specification document. This helps to identify flaws in the intended interface early in the development process.

    2. Create mock objects that emulate the behaviour of the intended module, with fixed input/output. This allows you to verify that you have the necessary data at each step, and also allows you to verify the algorithms without external dependencies.

    3. Implement the object.

    This strategy leads to loosely coupled / tightly cohesive objects, which are easier to verify with testing and easier to isolate issues when debugging.

    A similar strategy can be followed when debugging the code of your team members. Debugging manually is a very time consuming task, regardless of whether the debugging is done through code reading or with a debugger. Use this time more wisely and develop test cases that mirror the analysis you do during debugging.