Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

I never use the debugger.

by friedo (Prior)
on Jul 27, 2005 at 04:50 UTC ( [id://478467]=perlmeditation: print w/replies, xml ) Need Help??

I've been a professional Perl hacker for the past five years, and a very amateurish amateur before that. Over the years my skills have improved tremendously (when I started my first fulltime job, I didn't know how to use references, for example.) I have proceeded from simple utility scripts to large OO systems, mod_perl, giant database frontends, daemons, simulators, GUI applications and all manner of miscellany, but I can't recall ever using the Perl debugger. In fact, I know almost nothing about it. It has been my attitude that print is the most useful debugging tool, especially when coupled with Data::Dumper. If something goes wrong, I sprinke some prints here and there and watch the program flow. I spit out variables and instance data to make sure they are what I think they should be. If it's a daemon or background process, I log the debugging messages somewhere where I can look at them later. If it's a web-app, I like to send a <pre> tag with some Dumper output so I can view the data right there in the rendered template.

I think there's perhaps two possible explanations for my not using the debugger.

  1. Perl is just so damn easy, and when you're running with strict and warnings, and avoiding common pitfalls, it's difficult to run into a problem so horrendous that the above methods can't solve it.

  2. I am simply not working on challenging enough projects, and the things I do are at such a rudimentary level that debugger-worthy problems simply don't arise.

Naturally the second possibility causes me some concern. I want to continue learning as much as possible, and if I have stagnated I haven't even realized it until I started this meditation.

So I'm interested in hearing the experiences of other Monks vis a vis Perl debugging techniques. Are there instances when the Perl debugger is invaluable, and mere printing or logging will not suffice? Are there times when you must step through a program, instead of narrowing down the problem to a few lines of code and spitting out the potentially broken variables? Or have you found that while my methods may work fine, using the debugger is easier or more efficient?

Eagerly awaiting your replies,

friedo

Replies are listed 'Best First'.
Re: I never use the debugger.
by tilly (Archbishop) on Jul 27, 2005 at 05:26 UTC
    You should read Are debuggers good?. Then you should learn to use the debugger and try it so that you can make an informed decision on whether you personally prefer to use it for debugging.

      I remember reading that thread at the time (it was on my birthday :) and breathing a sigh of relief because I debugged with print statements and had somehow came up with the idea that real programmers used the debugger and hence I wasn't one. I still haven't gotten around to learning the debugger, I haven't found a problem that has necessitated it but maybe I am just not trying hard enough :)

      --
      Murray Barton
      Do not seek to follow in the footsteps of the wise. Seek what they sought. -Basho

Re: I never use the debugger.
by duff (Parson) on Jul 27, 2005 at 06:24 UTC

    I've used Perl for about 13 years and I've never needed the debugger. I've always solved problems through some combination of print statements and reasoning. I've used C for nigh on 20 years now and I've had similar experience there as well. I've used gdb maybe 3 times in the last 15 years.

    I tend to think that it's experience in tracking down mysterious pointer problems that has prevented me from using the debugger so much in C and the translation of that skill (or intuition) to perl that has made me never use the Perl debugger. It's also that I've mostly used Perl "at the surface" rather than delving deep into its innards.

      Interesting, I'm halfway between - I never use the perl debugger, but I use gdb extensively for debugging C programs (often perl itself).

      One difference is that when I'm looking at C code it's far more likely to be written by someone else, but I still use gdb for my own C code, and print statements for the rare occasions I'm looking into someone else's perl code.

      Another part of it is that I tend to find bugs in tools: I got into the habit of using a debugger for C programs to show me the assembler code for each statement, because one of the first C compilers I used had a lot of code generation bugs. When I encounter or suspect a bug in perl, again it's the C-level debugger I turn to, this time because I actually have the opportunity to fix the bug myself.

      Conversely, if I were to encounter a bug in gcc code generation and felt brave enough to try and fix it myself, I'd probably use both gdb and sprinkled prints to help me understand the flow.

      Hugo

Re: I never use the debugger.
by adrianh (Chancellor) on Jul 27, 2005 at 09:12 UTC
    Are there instances when the Perl debugger is invaluable, and mere printing or logging will not suffice?

    I'd say it's a very handy tool for understanding other peoples code.

    When it's appropriate it's a very user and well worth learning, but I think it can become a potentially dangerous when people use the debugger as first resort.

Re: I never use the debugger.
by holli (Abbot) on Jul 27, 2005 at 05:01 UTC
    There was a poll recently, and it seems you're not the only one who does not use the debugger.

    Personally I do same as you. If I ever use a debugger then the graphical one from Komodo, but never that darn overcomplicated command line tool.

    just 2 cents,


    holli, /regexed monk/
Re: I never use the debugger.
by spiritway (Vicar) on Jul 27, 2005 at 05:16 UTC

    Or maybe you are sufficiently experienced that you don't need to rely on the debugger. I think that as you gain experience you learn how to home in on various mistakes. You gain a sense of where things went wrong, and don't (always) need to spend as much time searching, as you did when you started.

Re: I never use the debugger.
by mkirank (Chaplain) on Jul 27, 2005 at 11:04 UTC
Re: I never use the debugger.
by brian_d_foy (Abbot) on Jul 27, 2005 at 20:35 UTC

    I've found that I tend to not use the debugger with test driven development, an appropriate level of refactoring (so subroutines aren't that long), and decent coverage with tests.

    I have used a lot of the debuggers out there, but I find most of them inadequate. Most of my work is module development, but debuggers want a script to run. I guess I could run a test script in the debugger, but if I have a nice test script, I already zero in on the problem pretty quickly. If I have to write a short script to isolate a problem, I find it pretty pointless to start up the debugger to run it.

    If I need something else, I just use print() statements, or have some sort of conditional logging turned on.

    The people have have tried to convince me to use one or another debugger are usually the sort that work on single scripts and modules from only CPAN (so they aren't debugging their own modules). I'm just not doing that sort of development, or looking for the same sort of errors they are. Your mileage may vary.

    No matter what anyone says, however, do what works for you. Give other techniques a fair shot, but use what makes you productive. Different people will like different things.

    --
    brian d foy <brian@stonehenge.com>
      The people have have tried to convince me to use one or another debugger are usually the sort that work on single scripts and modules from only CPAN (so they aren't debugging their own modules).

      Odd. I found the perl debugger especially valuable for deciphering other people's modules, especially for bugs in CPAN modules.

      For example, about four or five years ago, there was a bug in one of the PDF modules we were using; the author had clearly forgotten the /g modify on one of his regexps, so that only the first occurance of a given class of special characters was being properly escaped.

      I didn't have to grasp the entire PDF specification, nor the author's intent in implementing that specification, in order to detect and correct the bug, because I had a nice debugger to guide me, and show me what was going on inside all the tricky objects and methods and twisty maze of function calls.

      Especially with OO, where a function can return objects from different classes, each of which has their own special version of a method call, it's very nice to know exactly what function is being called, and which data is being passed, when all the code says is "call method X with object Y".

Re: I never use the debugger.
by astroboy (Chaplain) on Jul 27, 2005 at 10:57 UTC

    I'm sure that using the debugger from the command line can be a pain, but if you use an IDE (OptiPerl in my case, but Komodo has it too), then why spend the effort typing prints when you can step through the code, inspect variables in real time, set breakpoints - in other words save the the time keying in statements that you'll want to remove later.

    Having said that, I make extensive use of Log::Log4perl because I can leave in the debug statements but turn off the generation of log messages when I want to.

      I use print statements because that'll save me time stepping through code, setting breakpoints, etc.

      I'm often interested in the value of a variable after a few thousand iterations in a loop. I really don't want to step through that code, or set a breakpoint in that loop. Takes way too much time.

        There's nothing to say you can't do a hybrid approach if you're debugger is being annoying... which the perl debugger is sometimes. :-(

        Add a debugging conditional for the nth line of the loop, and set a breakpoint at it.

        In my experience, though, if I'm interested in the thousandth interation of something, there's something happening (a particular record, or database entry, or something) that triggers my interest in the 1,000th time through the loop versus the 999th time.

        If I can identify what that is, I can write debug code to detect the suspicious condition, and set a breakpoint for that. Then I can decide what to print out, and where to investigate from there.

        Unfortunately, the perl debugger doesn't seem to have a "detect this condition and break" function, and I sure wish it did. I consider it a flaw in the debugger when I have to write debug code by hand, but it's better than writing *all* the debug code by hand, only to tear it *all* out later...

Re: I never use the debugger.
by zentara (Archbishop) on Jul 27, 2005 at 12:43 UTC
    I've never used the command-line perl debugger either, mostly because the Tk gui to it, ptkdb, is so easy to use. But after awhile, even ptkdb isn't needed, because you learn little tricks like printing @_ first thing in subroutines to trace problems.

    BUT I will say ptkdb is quite handy when you are trying to figure out code that SOMEONE ELSE wrote. You can step right thru the program and watch your variables change at each step.


    I'm not really a human, but I play one on earth. flash japh
Re: I never use the debugger.
by Anonymous Monk on Jul 27, 2005 at 08:45 UTC
    Same here, except that I never use Data::Dumper. I don't like to read output that intended for 'eval'. In the rare case that I want a complex structure to be printed out when debugging (usually, I'm only interested in a few values - scalar I just print, arrays I just interpolate), I use YAML whose output is much better human readable than Data::Dumper's.

    And sometimes, I tie a variable to track the changes in its value.

    I seldomly use gdb as well, but then, most C programs I write are pretty small. Most of the time I use gdb is when perl segfaults, and I want a stacktrace to send with a bug report.

Re: I never use the debugger.
by DrHyde (Prior) on Jul 27, 2005 at 15:47 UTC
    The learning curve for sprinkling print statements is easy. The learning curve for using the debuggerer is hard, and provides little immediate benefit. So many people - myself included - don't bother learning the debuggerer, despite learning it providing a long-term benefit.

    Between print, Data::Dumper, Devel::StackTrace and Devel::Trace, I've yet to find a case where the debugger gives enough benefit to learn it.

Re: I never use the debugger.
by 5mi11er (Deacon) on Jul 27, 2005 at 15:01 UTC
    I've used the debugger less and less as time goes by, but, I personally find it a great tool to use when I'm attempting to get a semi-hairy, or worse, incantation just right, I'll open a window and run a debugger to play with it, and leave my vim editor in the other window, and copy and paste the incantation when I'm done.

    However, the debugger will always be an important part of my toolset. I find that remembering exactly how to call/use some of the perl built in's is lost on me; I'm always looking things up in the blue camel book. And sometimes, when I think I remember how to do it, I'll put it in wrongly, and only when stepping through the debugger does it become obvious that I'd messed it up.

    Yeah, print statements would work too, but I hate muddying up my code with those otherwise useless debugging print statements. Just chalk it up to personal preferences and all that.

    -Scott

Re: I never use the debugger.
by Popcorn Dave (Abbot) on Jul 27, 2005 at 16:21 UTC
    There are days I use Data::Dumper and print statements, but there are many more days that I use ptkdb. Once I found ptkdb, I was in heaven. No more sprinkling multiple print statemens throughout my code that I have to take out later.

    The editor I'm using has it's output window as a child window in the editor so when you do lots of print statements, you either watch them fly by or you get to scroll through them to find what you're after. With ptkdb, even if I'm watching complex data structures, somehow it's more pleasing to me to be able to see what the variables are doing as the program runs, than having to rely on print statements to watch.

    Now if I could just find one that would work for tracing Perl/Tk variables as the program runs...

    Useless trivia: In the 2004 Las Vegas phone book there are approximately 28 pages of ads for massage, but almost 200 for lawyers.
Re: I never use the debugger.
by bluto (Curate) on Jul 27, 2005 at 15:50 UTC
    When I used to write a lot in C, there were a few cases where debuggers were very useful as compared to just being a crutch. I could attach to a long running daemon to check out a bug that only occurred after the program had been running for days on end. Also, it was easier to observe the state of various data structures, rather than add/remove print statements or control flow changes and rebuild the code twice. If you really want to, you can also get better test coverage for code paths that are extremely unlikely to occur in real life, without altering the actual code.

    In perl, I have hardly ever used a debugger, and in the cases where I did, probably have never really needed to. Adding and removing things like verbose logging, Data::Dumper prints, etc, is just so quick and easy there is almost no point. About the only time I could forsee really needing it would be if I had to try to debug a problem that is occuring in production in someone else's perl code (e.g. a CPAN module), and I didn't want to alter their code for fear of perturbing some other process on the system. Hasn't happened to me yet...

Re: I never use the debugger.
by Your Mother (Archbishop) on Jul 27, 2005 at 17:01 UTC

    When I learned that Larry himself hardly, if ever, uses the debugger, I didn't feel so bad about my own reluctance.

Re: I never use the debugger.
by samtregar (Abbot) on Jul 27, 2005 at 17:12 UTC
    From my perspective there isn't very much difference between using the debugger and sprinkling print statements through your code. In either case you're running your program in a way which gives you information about its internal state as it runs. The biggest difference is the level of interactivity: the debugger offers immediate access during a run but print statements require a new run to take affect.

    I've used the debugger a few times, most often when I'm working on a program that takes a long time to get into a bad state. In this case the extra time needed to add a new print statement and get the result after a new run is too high.

    Another good use is to figure out what your program is doing when it's locked up and you can't guess a good spot to put a print. The debugger can answer that question very quickly indeed!

    -sam

Re: I never use the debugger.
by talexb (Chancellor) on Jul 27, 2005 at 21:19 UTC

    When I wrote C for a living, I followed these steps to make sure that there was very little room for misunderstanding between what I thought I'd told the code to do and what it was actually doing.

    • I compiled my code with maximum warnings on;
    • I linted the code and cleaned up all of the warnings;
    • I ran the code in the debugger and watched it do everything, while I tried to feed it circumstances that would exercise all of the code paths; and
    • I went back and editted the comments in the source code so that they were up to date and as clear as I could make them.

    After that, I was pretty sure the code would behave the way I expected it.

    This week I'm upgrading an install script that I wrote some time ago. It's not great code, but it's fairly decent. As usual, I want to add the new code so that I don't have to come back and hack it at 4am when things are broken. So I write the code, look at it, poke it, prod it, run it, fix it, then run it from the debugger, checking things as I go. As soon as something happens in the debugger that diverges from my understanding of what *should* have happened, I investigate and fix the problem, or realign my understanding of the solution.

    As before, once the debugger tells me the code is working the way I thought it was, then my work is substantially done. You can do it using Data:Dumper too -- I use that along with Logger::Log4Perl sometimes -- but developing with a debugger is something that I'll always do.

Alex / talexb / Toronto

"Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Re: I never use the debugger.
by leriksen (Curate) on Jul 28, 2005 at 06:09 UTC
Re: I never use the debugger.
by fizbin (Chaplain) on Jul 29, 2005 at 16:16 UTC
    I admit that I rarely use the debugger as it's intended to be used, but I find that I often use the debugger as a perl REPL, (Read-Eval-Print Loop) to do some quick manual testing of a new sub. Just run perl -d somefile.pl, and then type p mynewfunc('testvalue') to see the output.

    I guess I should add by way of context that most of the perl code we write around here isn't object oriented at all, it's just long driver scripts being used to kick off the "real" processing code. As such, it's almost all standalone scripts, so the debugger is really the easiest (and fastest) way to load up a file and invoke pieces of it when the file was not necessarily designed to be invoked piecemeal.

    -- @/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/; map{y/X_/\n /;print}map{pop@$_}@/for@/
Re: I never use the debugger.
by TedPride (Priest) on Jul 27, 2005 at 07:58 UTC
    Assuming you structure your program well and test properly at each stage, there's no reason why print and Data::Dumper shouldn't suffice for locating bugs. It's the stupid programmers who need advanced debugging tools, and they're the ones who won't understand how to use them :)

      I take great offense to your insulting generalisation. I use the debugger all the time, in addition to significant amounts of tracing. And, unless you're willing to back up your assertion that since I need the "advanced" debugging tool, I must be stupid, I'd really appreciate it if you'd strike that out of your original post.

      I find the debugger, even the text debugger, invaluable. Mainly because I can much more quickly find my problems than with print or logging (which I use as well). The print statements can help me narrow down a problem, but once I get to a certain point, I find it way faster just to set a breakpoint, continue to that point, and then I can look at variables, object method output, stack traces, etc., really quickly. I don't always know what I'm looking for when I get there, but I know I'll be able to query anything I need at that point. I can even run perl code (object methods, for example).

      The problem with print, for me, is that I need to know what to look for before I get there. And since some of my perl code literally takes hours to complete, if I'm debugging something near the end, I want to get there as few times as possible.

      I've also devised some infrastructure that allows me to bypass unneeded portions of the code - but it still can take 10 or 20 minutes to reach the point I'm debugging. Adding another 10 or 20 minutes each time I think I need more information is actually painfully slow, whereas with the debugger it'll take me 30 minutes to get there once (debugger is slower than regular code), and I usually don't need to go in a second time.

      To me, there are some similarities between goto and the debugger. You need to really understand the breadth of the debugging tools to be able to use the right tool for the right job. When you understand how to use the debugger, it can be powerful. But when all you have are print statements for debugging, everything looks like a variable - you may get the job done, but it may have been faster/easier if you used the debugger.

      Assuming you structure your program well and test properly at each stage,...

      ...and assuming that you wrote the !*#$$^!! code in the first place.

      It's the stupid programmers who need advanced debugging tools,

      I don't mind when people say "I never use the debugger...I just use print statements", that's fine if you never get into the situation where a debugger would tell you what you need to know without adding a single print statement, in fact, I just add print statements most of the time. But to call programmers stupid for using a debugger, is, well, stupid. At a previous job in a non-perl environment, I found it was the stupid programmers who didn't know how to use a debugger and spent days looking for a problem that I tracked down in a couple of hours with a debugger. When I was playing with AI::Prolog, I'd see code like $object->$method, and the easiest way to trace it was to fire up ptkdb and just step through that line of code. If you have the luxury of only ever working on your own code, then good for you, but don't go insulting those of us who don't.

      Assuming you structure your program well and test properly at each stage, there's no reason why print and Data::Dumper shouldn't suffice for locating bugs.

      If your design is perfect, and your testing is perfect, there are no bugs in your code, by definition. :-)

      Let's say you're debugging, and you're adding a bunch of print statements. And you keep making typos, and having to fix them, and take them out of code before it hits production, and so forth. And it's becoming a pain, and one day, you wake up, and realize that all your debugging code may itself contain bugs. Otherwise, you won't be able to find your bug properly.

      One way to attempt to avoid bugs in debugging code is to limit the complexity of code you write, so that you only write simple debug and trace statements. Unfortunately, you don't know before you run the program where the problem lies, so you don't know for sure what to print out: and printing everything will often drown you in a sea of output.

      Wouldn't it be nice if there were a known, tested, and reliable set of debugging code that you could use? That way, you wouldn't have to worry about typos in all those darned print statements screwing you up; you would be able to get just the output you want, as soon as you decide you want it, without having to re-edit and re-run the program over and over and over again!

      You'ld never delete a line of good code while trying to strip out all those print statements you added during the exploratory stages of your debugging. You'ld never let a debug statement slip into production. You'ld get the busy work of writing the same old lines of code over and over out of the way, and just concentrate on finding a fixing bugs.

      Doesn't that sound nice?

      Well, that's called a "debugger", and to me, that's why it's good. It lets you do the same thing that you do with print statements, except faster and easier, and it shields me against a few common kinds of stupid, time consuming mistakes.

      It guarantees that I didn't screw up a program by testing it. If you hand test my code by editing it to understand it, but claim you've made no functional changes, and then later my code breaks, the boss doesn't know which one of us really broke the codebase. If I test using the debugger, the boss knows it's not my problem, without auditing the codebase for changes and arguing over who changed what. It's one less set of diffs to run... one less thing to think about.

      Single stepping through the entire program is rarely the answer, but verifying the functions down the call tree is a quite reasonable way to track down a bug.

      Does the main program work correctly? No, because you're hunting a bug. Follow the following steps, and you'll probably discover your bug:

      1. Look for the design flaw or coding error at this level of the code. If you see it, you're done.
      2. If it's not here, look at the output of each of the subroutines called. One of them should be wrong (the bug is either at the level you're looking at, or further down).
      3. Step into the subroutine that's in error.
      4. Goto step 1

      You can do this same thing without a debugger, but it involves writing more code, and you have to re-run the program over and over. Debuggers run code a bit slower, but you don't have to write code to see what's gone wrong, and you can change your breakpoints (ie. where you put your print statements), and what you output as you go.

      It's the stupid programmers who need advanced debugging tools, and they're the ones who won't understand how to use them :)

      I personally think it's kind of foolish to avoid a tool that can solve my problem faster, but to each their own. Maybe I'm just a "stupid programmer", but again, I think my boss cares less about my IQ, and more about whether I can solve the problems that make his business run. To me, a good program is one that solves the job at hand, correctly, in the budget allotted, with an eye to future business needs.
      --
      Ytrew

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://478467]
Approved by planetscape
Front-paged by Enlil
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-03-28 16:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found