12 ms·
You can pry my debug prints from my cold, dead hands. I get the point this person is making, but at times (and depending on language) it's the fastest and most
by falsaberN1 5y ago
You can pry my debug prints from my cold, dead hands.
I get the point this person is making, but at times (and depending on language) it's the fastest and most efficient option. "Oh, the value is not what I expected" -> fix -> "value is good after testing, can remove the debug print".
It's not elegant, yes, but it does the job with zero preparation and works for every language.
Now if things are so hopeless the debug print doesn't even work, then yes, get a proper debugger.
- chii 5y agoThe fact that you _know_ where or which variable it is, and know where to put the print in order to see the value indicates that the bug is either trivial, or that you already have an idea of where the bug is! I argue that printf debugging is more difficult if you dont know _what_ is incorrect, or if you dont know where a value is being changed. Stepping through your code is a great way to find out. To me, actual stepped debugging is like having a print statement for every single line in the code base.
- falsaberN1 5y agoYou aren't wrong, but you do need a debugger to be available, and it's not the case with every language, unfortunately.
- stinos 5y agoI argue that printf debugging is more difficult if you dont know _what_ is incorrect Or even impossible? I use print debugging often, not even only in cases where there's no step debugging possible and/or I'm too lazy to fire up a config/software which allows debugging, but from time to time I encounter bugs which I really can't even begin to imagine how terribly awkward it would be without step debugging. For example: finding a bug in a mark&sweep garbage collector written in C which only occurred in certain LTO builds. To get a picture of the problem I stepped through assembly code while looking at certain memory locations, regsiters, the C stack, and some related variables. How would one tackle that with print debugging? Plus the print statements would affect the very thing being debugged? That should be fun. Not to mention the effort it took to even be able to reach the exact code location where all of this happened. Would almost require to randomly sprinkle print statements all over the place.
- misthop 5y agoIf you have _no idea_ where a bug could come from in your code You should spend the time understanding your codebase before you even begin debugging. At the very least you need to be able to reproduce your bug to reliably fix it. How can you have no idea where a bug is happening if you can trigger the error in a code path? EDIT: I don't want to go so far as to say that your example can never happen, but I can't believe there is any domain where it is the norm
- Jtsummers 5y agoEver inherited a 500k+ SLOC program with piss poor documentation that you can't rewrite (at least not within the needed timeframe)? Or worked in an office that, on some projects if not overall, experienced high turnover (due to promotions, internal movement, quitting, etc.)? It's very easy to end up with a project in a state where no one actually knows most of the code. A debugger shines here. In fact, the debugger can be a fantastic way to learn the code since the dynamic behavior of a system can often be hard to infer from its static representation (looking at you WPF and XAML, or any project where architecture astronauts went hog wild with certain design patterns).
- misthop 5y agoChanging code that you don't understand because you "found" the bug with a step through debugger is a recipe for disaster. In those situations (high turnover/fast moving tech debt accumulation) perhaps no one cares that the code base is becoming unmaintainable, but it isn't a good practice.
- Jtsummers 5y ago> Changing code that you don't understand because you "found" the bug with a step through debugger is a recipe for disaster. I don't get your point, because that's not what I suggested someone should do. I think (on rereading my original comment) my point was the exact opposite: Develop an understanding of the code through the effective use of a debugger: > In fact, the debugger can be a fantastic way to learn the code since the dynamic behavior of a system can often be hard to infer from its static representation (looking at you WPF and XAML, or any project where architecture astronauts went hog wild with certain design patterns). You seem to have inferred something from my comment that I did not say.
- gus_massa 5y agoJust add more print instructions. And if that doesn't work, add even more print instructions! Add some instructions to print "**1**", "**2**", "**3**", ... to see how far the program goes, which branches it takes, print a few variables that look interesting. If that fails print the uninteresting variables, remove "**1**" and add some "**2a**", "**2b**", ... in between 2 and 3 ... After a while, you discover the correct spot and the correct variable, and the error is trivial.
- rgoulter 5y agoI do this too; but it seems to me this is the case where using a debugging tool would probably save more time. Looking at the effort involved: here you have to spend the time to add a bunch of print statements throughout bits of code; then compile/run the program (repeating until you've found the right place). With a debugger: you'd have to take the time to set up the environment and learn how to use it (e.g. set breakpoints in parts where things would be interesting). But then the "look at interesting values" wherever isn't significant additional effort.
- scoutt 5y agoI am sorry, but this approach seems terrible. It seems the thing I do when I have to debug something I don't know, like PHP ("echo hello1", "echo hello2"). And that is just because my field is far from web development (I do embedded C), and I might be forced to do it like once every 5 years or so. I don't know if you program for a living, but I would be kind-of ashamed if I see a colleague debugging like this. It seems a desperate approach.
- danaris 5y agoThat's quite a judgement when you have no idea what kinds of tools the language the person you're responding to is using has. Frankly, even when I'm using a language that has a stellar GUI debugger, there are times when print debugging is vastly more effective. Why? Because I have a loop that iterates thousands of times, and crashes on some indeterminate but high iteration. A simple line-based breakpoint requires me to manually continue the code thousands of times, then take note of what state the variables were in the time just before it crashes. Even the ability to set a more complex variable-value-based breakpoint doesn't help that much when I don't know what the values are where it breaks. Printing out the loop variables every time lets me just check the last printout, and say, "Ah, it's when it hits i=37129", then follow that to the array value it corresponds to, with a substring in it that just happens to trip an edge case of one of the calculations. Or whatever.
- db48x 5y ago> it works for every language This is really the problem. Nobody has spent time and money to make debugging _good_ in the languages you use. Few people pay for good tools any more, and only a tiny fraction of users ever contribute improvements to the open–source tools they use (paid or otherwise). So the average debugger hasn’t gotten better since the 90s. I do programming in multiple languages too. In those where I can use RR and Pernosco, I use them every time. In those where I can’t, I miss RR and Pernosco every single time.
- jjoonathan 5y agoYep. The other day I was: * Debugging an 8 bit microcontroller in-circuit with an IDE, conditional breakpoints, step in/out/over, full stack visibility, and the ability to manually poke at values/memory/io * Debugging an AWS lambda function with printf and high latency logs It doesn't matter how hip, how modern, how fast, or how big the environment is. What matters is whether or not the ecosystem cares enough to make debugging nice.
- incrudible 5y ago> AWS lambda Live by the sword, die by the sword.
- corty 5y agoNow if the sword strikes would only leave a GDB stub...
- sillysaurusx 5y agoWhy isn't print debugging good? Seems good to me. As pg said, it's like scrubbing dishes with your fingertips: rarely discussed, highly effective.
- db48x 5y agoPrint debugging is sometimes acceptable. Scrubbing dishes with your fingertips totally works, but we all have dishwashers. Dish–washing machines are way better than scrubbing manually, with your fingers or with anything else. Load the dishwasher, then go do literally anything else while the dishes are washed. Even if all you do is go watch television, you will be better off just because you didn’t stand there scrubbing dishes by hand for an hour. More human potential has been wasted by drudgery than by any other cause. Print debugging is like scrubbing dishes by hand, and neglecting your dishwasher. Pernsoco is like those commercial dishwashers that blast the dishes with super–heated steam to wash them in a few minutes instead of 45.
- oregontechninja 5y agoCame to comment this. Print debugging makes me so fast at work. Unless you give me an easier and better tool I so no reason to change. Works in every language, exactly how I'd expect, and is exceedingly easy to explain to others.
- NDizzle 5y agoYep. You can blow peoples minds in ANY LANGUAGE by using print debugging sometimes. It's amazing, but true. At least it's been that way for the ~25 years I've been doing it. You think you're here? Let's put a few print statements in there to confirm your execution path is actually what you think it is, and those values are what you expect them to be.
- OJFord 5y agoI use prints a lot too, but you must admit: > You think you're here? Let's put a few print statements in there to confirm your execution path is actually what you think it is, and those values are what you expect them to be. You could just put a breakpoint there, look at as many values as you want, and not have to re-run it if you think of another.
- ysavir 5y agoTrue, but I don't want to have to exit out of 5 breakpoints each time I run through the scenario. I just want to run it with the print output logging the procession and key variables as a summary of relevant info. To me that's the key difference. If I know what I'm looking for, prints are great. If I don't know what I'm looking for, breakpoints are a must.
- spelunker 5y agoPrint debugging makes me fast too, but there is eventually a breaking point (get it) where print debugging isn't getting me the answers I need and I have to switch to using other options like interactive debugging. Still though, I reach for print debugging first.
- 5y ago
- scarygliders 5y ago100% this. Have looked at, say, the Python debugger as used by PyCharm and thought "well this seems like a bludgeon, I only need to see how <variable> isn't working as expected" and bung in various print() statements in and around the Thing concerned, sprinkling them wider and wider if the bug isn't localised to a function or even the class it's in - I may have supplied naff information to a class when instantiating it, for example. Debuggers are simply too much of a complicated bludgeon. I can understand a need for debuggers for machine code/assembly programming, or deep system programming when you're hitting the metal, or even low level languages like C. I've yet to find a need for a debugger for high level languages like Python. Perhaps some day. Until then, I'll plough the time which would be required to Get To Know the debugger, into writing code.
- gnud 5y agoI really don't understand this. Whenever I try to print debug, I end up missing the mark on my first print statement(s). If I just set a breakpoint, I can jump back in the stack, or step forwards, so I can easily find the real place the error happens. Of course I sometimes still print debug - when using languages with bad debuggers, languages where I don't know the tooling, languages with horrible control flow (javascript callbacks), or constrained environments, printing/logging is sometimes the best you can do. But that doesn't mean it's the best there is.
- bsder 5y agoIt's kind of funny, but Python is the only language I regular use the debugger--presumably because it's built-in. I put "if (condition): import pdb; pdb.set_trace()" all the time and almost never use "print". So, clearly I don't love "print", I just hate debuggers that are annoying to set up. I suspect that if other languages had such a convenient "drop me into the debugger" statement, more people would use debuggers.
- db48x 5y agoThe “debugger” keyword in Javascript is similar. I’ve used it frequently!
- fassssst 5y agoA good debugger lets you add print breakpoints, so you can add more print statements at runtime as needed.
- rrobukef 5y agoYou could, but then you're programming in yet another language, at the same time, on one single line, without type-checking, maybe without turing-completeness, functions or expressions.
- yndoendo 5y agoAgree. Print debug with compartmentalized domain tracing using flow control to print or not print is the only way to debug live life safety embedded systems. 1. Ability to prevent wasting resources on a system that does not need to be debugged. 2. Retain most print debug branches that were useful. 3. See how the internals are functioning on a live system with the issue that has yet to having a lab level proof.
- AnimalMuppet 5y agoEmbedded systems, where there are timing things going on, are an interesting special case. You can't just hit a breakpoint without (in the worst case) causing physical damage. It's even worse if it's multithreaded as well. If you hit a breakpoint, one thread stops and the others keep going, but they keep going in an environment where one thread is effectively dead (the one at the breakpoint). Everything is invalid from then on, in all threads. So breakpoint debugging is certain to be doomed. Print debugging is not doomed, but it's challenging. The problem is that the time to print out the message can change the timing, and therefore change what happens. It's not certain to do so, but it's something you always have to keep in the back of your mind: "What if this changed the sequence? What if what I'm seeing in the printouts isn't what I would see if the printouts weren't there?"
- jghn 5y agoI think that print debugs are a great first step. The problem are people who can't use a proper debugger, but that's not the same as saying print debugs are always bad. I tend to use print debugs in two cases. One is when I'm pretty sure I know what the problem is, and it seems trivial. It's often faster to just confirm & fix that way. The other is when I am not even sure where to start, so I put a few canary prints here and there based on hunches until I start to narrow in mentally on what the issue might be. Beyond that, it's a proper debugger.
- m463 5y agoIt seems to me like the debugger analogy is that "you should use power tools to make all home repairs". No, it's quite possible to have a screwdriver in your pencil holder and turn it manually at the moment you need it. "Low tech", yet quick and precise and no batteries to charge.
- ajross 5y ago> You can pry my debug prints from my cold, dead hands. I clicked on this about to type exactly that phrase. Here's why: the CORE PROBLEM of debugging has nothing to do with process, it's the need for the human developer to understand the operation of machine code when faced with a specific set of runtime conditions. You can't debug by just reading code, because the bug only shows up at runtime. Most people agree with this. Likewise, you can't debug just by WATCHING a program, for the same reason. You need to be reasoning about the operation of the abstracted code at the same time. And almost always you need to be inspecting and reasoning about the internal states driving the behavior. Debugging tools, as nice as they might be, can only do the "watching" part. They are a fine way to do it, but you still need to be making the decision, based on careful analysis of the code, on which elements to watch. So... given that you're staring at code in your editor and thinking about how to extract the needed internal state to validate your predictions... why not just print it? That is: print/console debugging isn't a hard task you "have to do" in the absence of a fancy debugger, it's exactly the task that you must do if you're going to solve the problem. The fancy debugger, at best, is only saving your the time taken to TYPE the printf() expression. And in practice even that tends to parallelize with the analysis in my experience, as you realize things while typing out their expression.
- db48x 5y agoPernosco lets you record your program once, then query the resulting database over and over. This is like adding printfs to the program after it has run, any time you have a new idea for what it should have printed out. Here’s a demo: https://pernos.co/about/expressions/ https://pernos.co/about/expressions/ Notice in this demo how he clicked on a line number, and got back a list of all the times in the program where that line was executed. Not just a single breakpoint with the option to continue, but all of them. Then he queries for the value of a variable at all of those points, and gets all the values printed out simultaneously, as if there had been a printf at that line. Then he filters the list to show only calls made on a specific object, as if the printf had an if statement around it. All without needing to rerun the program, or even be on the same computer as where the recording was captured. This is what the author means when he says that all debugging tools can be _better_ than printf debugging, if only we put some more time into improving our tools.
- horse666 5y agoHeh. Aaron Patterson (aka tenderlove), core Ruby and Rails contributor, agrees with you. Although maybe not as forcefully :) https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debugger...
- rantwasp 5y agoI take it even further. Debuggers have to go and print statements should be converted into log statements where appropriate. The reality is that you're not going to attach a debugger to a production service. If you are doing things correctly and have separate environments for test/integ/prod you are not going to attach a debugger. Even if you can attach a debugger, the odds of you catching something are pretty small (not talking about trivial things). So you should: 1) instrument your code and have the proper debug/verbosity log levels for things 2) have a trivial way of altering the log levels 3) have a way to fetch the logs and diagnose what is going on solely based on the logs (and hopefully with something as simple as grep). This is the way. There are times and places when debuggers can be useful, but in most situations I see them as a crutch that adds more friction instead of accelerating solving the problem