TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

“I think the vast majority of developers still debug using print() statements”

189 pointsby FatalLogicalmost 3 years ago

93 comments

sphalmost 3 years ago
I used to debug frequently when I coded on Win32 GUIs 20 years ago and running the debugger was as simple as pressing F5 instead of F9. Nowadays, with a multitude of languages, setups and editors, I don&#x27;t even bother. Even setting up JS debugging under VSCode, which supposedly is a core feature, has always been an exercise in frustration every time I&#x27;ve tried it.<p>Rarely I run gdb when I&#x27;m debugging a particularly hairy C issue, but with any other language I don&#x27;t even bother and add prints everywhere. The JS &quot;debugger&quot; statement is pretty useful, but it&#x27;s still very awkward compared to the golden standard of Microsoft IDEs from two decades ago.<p>Don&#x27;t blame the users, blame the tooling, editor and language developers that never cared for delivering a good debugging experience.
评论 #31619123 未加载
评论 #31617580 未加载
评论 #31618178 未加载
评论 #31615772 未加载
评论 #31616527 未加载
评论 #31616091 未加载
评论 #31618357 未加载
评论 #31619324 未加载
评论 #31625201 未加载
评论 #31621462 未加载
评论 #31620257 未加载
评论 #31617981 未加载
评论 #31622044 未加载
评论 #31642703 未加载
评论 #31619080 未加载
marssaxmanalmost 3 years ago
Sometimes the print statement is the best tool for the job; sometimes it is the <i>only</i> tool for the job. If you know how to debug by adding print statements, running a test, and reading the resulting log, you can solve any problem, in any environment, on any platform[1]. Other tools may well provide faster results in specific situations, but one has to balance the time spent learning &amp; managing fancier tools versus the time spent getting the job done.<p>1) Well, okay, there are exceptions. Perhaps you have to find a spare IO pin attached to an LED, and make it blink at you in morse code, because your serial port hasn&#x27;t come up yet, so you can&#x27;t print to the console; but it&#x27;s the same idea.
评论 #31623749 未加载
评论 #31617940 未加载
评论 #31618731 未加载
评论 #31618026 未加载
评论 #31618873 未加载
评论 #31618079 未加载
评论 #31619407 未加载
评论 #31617172 未加载
srazzaquealmost 3 years ago
I don&#x27;t quite understand the argument here. Logging statements and &quot;using a debugger&quot; are not enemies of one another, with tribes of people in one camp versus the other.<p>Logging, done well, will inform (1) exactly what version of your code you were running 3 months and 12 days ago, and (2) where the potential issue may be.<p>Therefore it will inform you _where to place a breakpoint_ should you wish to repro the issue and debug locally.<p>Good luck getting started in a local debug session without having had adequate logging in place.
评论 #31619520 未加载
评论 #31619370 未加载
评论 #31619045 未加载
评论 #31621589 未加载
评论 #31619576 未加载
评论 #31619570 未加载
评论 #31623889 未加载
评论 #31622556 未加载
jraphalmost 3 years ago
This is often laughed at, but I think this is fine. Whatever helps debugging efficiently.<p>And debuggers have their uses too.<p>Printing is my usual way of debugging. I use &#x2F; switch between various languages that have unequal support for interactive debuggers with different interfaces, in various contexts where debuggers are not always usable. Printing &#x2F; logging always works the same regardless of the language and the context.<p>Step by step often looses me, and print forces to think about what and where to print so it also has its advantages.<p>Interactive debugging has a big advantage: no need to recompile &#x2F; reload each time you need to check out the value of a variable at a new location in the code.<p>But yes, the fact I switch between languages and contexts seems to encourage me to use generic tools that work okay for every language and context instead of specialized tools, so Kate and printing it is. But you can become efficient anyway, and for a task where printing is not enough, you can always spin up the heavy tools.
评论 #31617618 未加载
评论 #31614844 未加载
评论 #31618567 未加载
评论 #31621759 未加载
评论 #31616131 未加载
jiggawattsalmost 3 years ago
I just had a conversation with a dev manager about how the vast majority of dev teams I&#x27;ve encountered use maybe 5% of the tooling available to them.<p>Debugging using <i>just</i> debug tools in the IDE is just scratching the surface.<p>A demo I like to do is Azure Application Insights, which takes memory snapshots of web server processes in production whenever they throw exceptions. Combined with source indexing, it lets you &quot;debug&quot; a release build from a month ago in a matter of seconds.<p>Just recently I was trying to do the sales pitch to a semi-technical product manager, and he mentioned that they were seeing &quot;occasional login issues&quot;. While on a video conference session we managed to repo the issue: after entering a valid password, the application promptly reloaded the login prompt without any error message.<p>Sit down and think about how long you would estimate a bug like this would take you to fix: &quot;Occurs in prod only, infrequent, no error message, just does nothing.&quot;<p>App Insights helpfully had a &quot;debug snapshot&quot; available for the error. It was literally a <i>single click</i> to load it in Visual Studio. It jumped straight to the line of code that crashed, where there was a comment along the lines of &quot;we may be too lax in parsing this&quot;. The snapshot let me inspect the variables and... yes.. a bit too lax they were.<p>I did this in about two minutes <i>while chatting</i> with the manager. Boom. Solved!<p>I&#x27;ve had similar troubleshooting sessions in the distant past that took weeks or even months to resolve, because I just didn&#x27;t have the tools available to me.<p>Tools make all the difference, and anyone who argues against this just doesn&#x27;t &quot;get it&quot; in my opinion. I don&#x27;t care how wizard you are at shovelling, you aren&#x27;t going to out-perform the back hoe.
评论 #31621724 未加载
评论 #31620039 未加载
评论 #31619085 未加载
评论 #31619117 未加载
评论 #31622494 未加载
评论 #31624724 未加载
评论 #31620486 未加载
评论 #31623260 未加载
Noumenon72almost 3 years ago
I&#x27;m at my least productive when I can&#x27;t use a debugger (Jenkins jobs, nginx config, networking stuff). Everywhere else, getting it set up is my top priority.<p>* I usually fix the bug right there in the debugger where I find it. It&#x27;s so much easier to fix logic in a REPL with all the actual variables available then in a slow guess-and-rebuild cycle.<p>* Being able to inspect complex objects is so much more convenient when you can right-arrow your way through the levels or watch a nested subpath.<p>* I&#x27;m constantly surprised and confused as I make my way through code. Reality contradicts my assumptions at every step so I need the ability to see that to find my way to the bug at all.<p>* I love log statements, but I typically need the debugger to find the place to add the log statement. There are so many candidates I&#x27;d have to add five prints for every one I use.
评论 #31617957 未加载
someweirdpersonalmost 3 years ago
Different problems, different strategies, different tools.<p>Does it crash? Debugger, backwards from the crash.<p>Is there some &quot;wtf is going on &#x27;here&#x27;&quot; with a pretty undefined &#x27;here&#x27;, and only sometimes under unidentified conditions, but likely algorithm-related? logs, assertions, printfs. Until some more clear idea of the source of the problem manifests.<p>Does the former turn out to be truely bad, in the sense of unintended side effects e.g. by something writing beyond valid addresses and it is known what is being overwritten? Debugger.<p>Finally, is there some misbehavior in some already identified range of code? Debugger.<p>Of course the environment matters, too. Build time vs. debugger features available.<p>Most effort&#x2F;time is needed to solve wtf-style problems. As such, a significant part of the time&#x2F;effort can plausibly spent for some form of printing.<p>The last kind of problem (bad part of the code already known) doesn&#x27;t usually need a debugger: If the faulty part is already narrowed down, it is easy to spot the problem with eyes in most cases (at least knowing the intended behavior, maybe not when looking at some random unknown code).<p>Summary: More problems can be solved using a debugger quickly, but more time is needed to trace down those problems that cannot.
评论 #31621850 未加载
bluenose69almost 3 years ago
Although I find breakpoints to be helpful in some simple cases, for complicated work I prefer the print() approach because I can do complicated calculations before deciding whether to print (and what to print).<p>Plus, saving the information in a file is very handy, because it lets me examine state in some detail, with split editor windows, grep commands, etc. Quite often I&#x27;ll preface the print() output with special tags that I can use to sift through the log in an editor or, in more complicated cases, with code that analyses the condition numerically or graphically.<p>I&#x27;ve been doing this for several decades. It ain&#x27;t fancy, but it works. Compared with debugger actions like breakpoints, this helps me solve my problems much more quickly, and with greater insight.<p>Reframing Graham&#x27;s statement at an individual level, print() is what I use, the vast majority of the time.
评论 #31618871 未加载
WalterBrightalmost 3 years ago
I use debuggers usually for the stack trace.<p>I use print&#x27;s for most everything else. The reason is pretty simple - the print&#x27;s customize the dump for the specific problem I&#x27;m trying to track down. Using loggers generated far, far, far too much noise and not enough signal.<p>When the problem is found and fixed, I use `git diff` to find all the added debug logic, and delete it before checking in.
评论 #31618519 未加载
评论 #31618179 未加载
fsocietyalmost 3 years ago
I find the distinction between step debugging and runtime debugging to be more useful.<p>Someone who steps through every line of code will probably take longer to find the bug, and will spin cycles on rabbit holes and false paths.<p>Someone who uses “runtime debugging”, or rather has a hypothesis on the bug or what a piece of code is doing and uses a debugger or print statement to verify that will find the bug much quicker.<p>With this mental model, you can see how print statements can be as effective as a debugger in many scenarios.
评论 #31615037 未加载
评论 #31617879 未加载
samsquirealmost 3 years ago
I don&#x27;t think debuggers are superior than print statements or Jepsen.<p>I work with multithreaded code and lock free data structures.<p>I don&#x27;t use a debugger. So I rely on having a model in my head that could be wrong and what I plan to do is analyse logs after a test run. These are guaranteed interleavings that actually ran.<p>When you have 100 of threads and random interleavings your mental model is problem is necessarily different to thinking I&#x27;ll reach to the debugger to tell me what the program is doing.<p>When you want serializability you need to design your system differently. I implemented multiversion concurrency control and use timestamps for correctness. I have yet to write a TLA model for it though.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;samsquire&#x2F;multiversion-concurrency-control&#x2F;issues&#x2F;4" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;samsquire&#x2F;multiversion-concurrency-contro...</a><p>I also want to test my Raft implementation which isn&#x27;t properly threaded. But I also need to test pathological cases such as old raft nodes coming back.<p>Most of the time you&#x27;re reaching for the debugger is that you don&#x27;t understand why your web framework got into such a state where something is null such as your Inversion of control Java container as the control flow is so complicated. It doesn&#x27;t help with multithreaded programming.
评论 #31622454 未加载
bitlaxalmost 3 years ago
“The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.” — Brian Kernighan, “Unix for Beginners” (1979)
评论 #31614338 未加载
ChrisMarshallNYalmost 3 years ago
For my server work, I almost exclusively use print(). That’s mainly because I don’t spend much time there, and it’s not worth it for me to spend the time setting up xdebug, or whatever. It’s worked fine. I’ve written some pretty huge systems, that way.<p>For my client (native Apple) work, I use breakpoints all the time, but they are not always that useful; especially when working in a threaded&#x2F;time-critical environment. I often add print() statements, to display aggregate and calculation results. Swift has a fairly nice reflection system, that can be used to rabbithole a lot of information.<p>When running in debug mode, my console spews out all kinds of stuff. It can be a firehose, so it works best, coupled with breakpoints.<p>Been debugging for over 35 years. I’ve learned use whatever tools are available, but my most useful tool is in my noggin.<p>Those of us &quot;of a certain age,&quot; that have done firmware development, may remember ICEs (<i>I</i>n-<i>C</i>ircuit <i>E</i>mulators). These would probably be impossible to do, these days, but they were about the best debugging tool you could ever hope to have.
hysanalmost 3 years ago
Use the right tool for the job? For quick sanity checks and bugs that you are pretty sure about, sometimes it’s just faster to chuck in a print statement. Or if you want to just quickly see a stream of info at different points, throw in a bunch. Other times, you need the control and context provided by a debugger, so use it then.
rwmjalmost 3 years ago
It&#x27;s not helped by gdb and DWARF debuginfo being objectively terrible. There should be no circumstance where the value of some variable has been optimized out. That happens so often that to use gdb I have to recompile with optimization off, so I might as well add print statements. The CLI of gdb is also awful, with common operations like printing arrays or memory being hard and obscure. There&#x27;s a TUI, if you remember the key to get into it, but you wouldn&#x27;t know about it because despite the verbosity of gdb start up, it doesn&#x27;t tell you about it! And the manual is an info file, possibly the worst documentation format invented.
评论 #31619446 未加载
评论 #31618521 未加载
wruzaalmost 3 years ago
In my experience, debuggers are only useful in stepping over someone’s code. In your own code, a logging^ output is simply faster to read and reason about. It is like a trace of debugger, but you don’t have to set up sessions with different watches and conditions every time you start a project. I rarely want to “step”, I want to see the path. That “still debug using print()” part is misleading. Debuggers suck by design. Loggers <i>are</i> the better debuggers.<p>Also, if you don’t log and someone asks you “what was that yesterday” (not necessarily an error), good luck with your debugger-only approach. Logs are everything - ask your sailor, pilot, vehicle maintenance guy, credit manager.<p>If I was forbidden to log and was asked how to make a debugger better, I’d say that it should use #preprocessor directives right in modules, in which I could set up watches, object dump conditions, i.e. essentially logging. Please realize that at the end of the day all debugger does is printing something conditionally. But then why not just use plain ifs and prints (and few “if (DEBUG_ENABLE)” in case you want to omit it from the executable).<p>^ doesn’t matter if it is console or some service, as long as you can see it in real-time
评论 #31617730 未加载
cageyalmost 3 years ago
99.9% of the time (long-term personal C++ project) I use printf-based logging to root-cause unexpected behavior. I use gdb only to root-cause segfaults (which are thankfully quite rare).<p>I use GCC exclusively, and its type-checking of param types vs format string largely prevents me from spending time in gdb; pre-GCC adoption, the biggest source of segfaults in my world was printf type mismatches.<p>Addendum:<p>I&#x27;m sure it violates every coding convention ever created, but, in almost all cases, once I add a debug printf to my source code, for example,<p><pre><code> ED &amp;&amp; DBG( &quot;%s&quot;, foostr ); &#x2F;&#x2F; ED is usually a function-scoped enum normally ==0 </code></pre> <i>I leave it there forever</i>. This allows all DBG&#x27;s to be eternally subject to GCC printf param type build time checking going forward (preventing the debug print code from rotting (as it absolutely would if commented out), at minor maintenance cost (typically only when I switch to a new GCC release)) while not imposing any runtime cost (unless I flip ED to 1 and rebuild to enable function-specific detailed logging).<p>As far as this practice injecting large amounts of comprehension-thwarting noise into my source code: all such `ED &amp;&amp; DBG(...);` code sequences are positioned in their own column far to the right of the non-DBG code (needless to say, I don&#x27;t subject myself to 80-column coding-convention limits; more like 160-column). That this results in multiple statements per line (another typical taboo) is a don&#x27;t care, since I&#x27;m never using a debugger to single-step thru code, and in any case, by convention my DBG() calls <i>never</i> modify program state.<p>It works great for me, but probably not for anyone else.
评论 #31617464 未加载
评论 #31617454 未加载
rocaalmost 3 years ago
Old-school interactive debugging tools like gdb and Visual Studio are pretty bad. But new-school debuggers with record-and-replay and features built on top of that --- e.g. rr-project.org, undo.io, replay.io and (plug) pernos.co --- remove a lot of the downsides of &quot;stop and step&quot; debuggers and add a lot of extremely useful features on top.<p>E.g. in Pernosco you can capture most of the benefits of logging by querying for the executions of a particular line, filtering on a conditional expression, and rendering the values of chosen expressions at that line: <a href="https:&#x2F;&#x2F;pernos.co&#x2F;about&#x2F;expressions&#x2F;" rel="nofollow">https:&#x2F;&#x2F;pernos.co&#x2F;about&#x2F;expressions&#x2F;</a> ... except that you get those results without having to recompile or even rerun your program. And when you find the event you&#x27;re looking for, you have instant access to the complete program state with the full power of the debugger. replay.io has something similar.
chucklenorrisalmost 3 years ago
I don&#x27;t think anyone is arguing that print debugging isn&#x27;t useful or is somehow archaic. That&#x27;s a straw man. What the author and I experienced is that the vast majority of developers don&#x27;t use an incredibly powerful tool when it&#x27;s available, and relatively easy to set up. I personally saw developers go through compile time cycles of 30 minutes to add and remove print statements than to bother using a debugger. Most people don&#x27;t understand what&#x27;s a stack view, or memory dump or the fact that you can modify variables at runtime to skip conditional checks to avoid recompiling. On dynamic languages it&#x27;s even better, you can easily evaluate code, replace functions, import modules and call other unrelated functions, etc. That saved my bacon noumerous times in production with nodejs and python. Just connect to the container, send sigusr1 to the process to open the debug port, forward that to my machine and then connect my debugger and run code&#x2F;json dump large data&#x2F;put a conditional breakpoint and wait for that hard to reproduce bug to come to me. This kind of silly stuff got me &quot;wizard&quot; status in orgs i&#x27;ve worked in over the years and substantial pay raises over devs that were more conscious&#x2F;hard working than me.
rektidealmost 3 years ago
I had a good long while where I made the debugger my habit &amp; used it well. I have fallen off the path.<p>Part of the problem is I often am looking at interactions across systems, so just having a bunch of logs is helpful. Versus having a bunch of debuggers open. Learning the logs also helps me get better at debugging prod: using what&#x27;s available. But I also add in a bunch of random `console.logs()` too.<p>I&#x27;m looking forward to tracing becoming a more regularly used tool. Being able to see a timeline, across services, is hugely powerful. I hope some-day we design languages that either integrate tracing, or, ascending into high-fantasy, languages where the runtime itself starts to be powered by tracing-like structures, where the tracing also serves like event-sourcing for your galaxy. Innovating on language capabilities, rather than just ever-struggling with language syntax &amp; capabilities &amp; types, feels vastly under-explored.
mrwhalmost 3 years ago
I know I do. And I know I used to feel a bit guilty about it, that a real software engineer would use some fancy debugger. There are plenty, I work at a FAANG. But as others have pointed out, printf is often the best approach. It&#x27;s iterative and repeatable. I don&#x27;t feel at all guilty that&#x27;s it&#x27;s my go-to approach now.
评论 #31617852 未加载
评论 #31617787 未加载
whacked_newalmost 3 years ago
Kovid Goyal, the author of calibre, has this in the official developer documentation [1]<p><pre><code> Using print statements This is Kovid’s favorite way to debug </code></pre> and he&#x27;s gotten really far with it. Granted, he is not the average developer.<p>[1] <a href="https:&#x2F;&#x2F;manual.calibre-ebook.com&#x2F;develop.html#using-print-statements" rel="nofollow">https:&#x2F;&#x2F;manual.calibre-ebook.com&#x2F;develop.html#using-print-st...</a>
评论 #31617939 未加载
评论 #31618627 未加载
bawolffalmost 3 years ago
Wow the pro debugger people here are really defensive, saying that the only reason people wouldn&#x27;t use a debugger is incompetence. Sheesh, get over yourself.<p>You use what works for you, i will use what works for me. Which is sometimes a print and sometimes a debugger depending on circumstance.
评论 #31618125 未加载
评论 #31619467 未加载
Amboliaalmost 3 years ago
&quot;prints&quot; give you an immediate picture of the whole execution, if you place them properly. A debugger leaves you isolated in one specific part of the code and you have to crawl out of there with navigation tools that usually are not very good.<p>The only time I find debuggers useful is if you can tell the issue from the current value of the variables, or if the issue has already been isolated to something like a tight loop of 10-20 lines that are doing a tricky operation.
bpyealmost 3 years ago
I&#x27;ll use whatever works best for the problem. I normally start by trying to step through in a debugger, but often that is too slow so I&#x27;ll introduce some extra prints and&#x2F;or tracing - and try again. Conditional breakpoints might work for some folks but when doing kernel level development I&#x27;ve always found them too slow to really be useful.<p>The biggest issue I have with prints is that I need to recompile, deploy my change and reboot - probably getting towards 10 minutes, whilst with a debugger I can inspect additional state without any work, and some times even do some limited patching to fixup variables or replace something with a NOP.
WalterBrightalmost 3 years ago
In the early daze I was debugging the software I wrote for an embedded system. I wanted to make sure the interrupt service routine would run fast enough that cascaded interrupts didn&#x27;t happen.<p>The easiest way was to simply attach a wire to the interrupt pin in the CPU running to a speaker.<p>The resultant buzzing was all the info I needed. (Human ears are very good at detecting patterns.)
IYashaalmost 3 years ago
I do. It is by far the most portable way of doing things, if not the most reliable (but it may also slow things a lot). When someone asks me to help debugging in unknown language, on unknown platform, the first thing I ask is: &quot;how do I printf here&quot;. Most of the problems are traceable this way. It is VERY rarely a low-level (reg&#x2F;stack&#x2F;mem&#x2F;system) fault.
kallebooalmost 3 years ago
When debugging Xcode projects I 100% use the debugger - even when doing print debugging (for e.g. hard to pinpoint UI bugs) I&#x27;ll use print breakpoints since you can add&#x2F;remove&#x2F;edit those without recompiling&#x2F;relaunching.<p>When using something like JavaScript or PHP where the tooling is finicky and fragile I just give up and use 100% print debugging.
评论 #31617556 未加载
kgeistalmost 3 years ago
Stepping with a debugger is OK as long as the piece of code you are debugging is more-less single-threaded. If your system is event-based with a ton of background processing, I found that debugging via logging is much simpler to set up and use in that case. It also blurs the line between debugging a problem locally and in production (including post mortem), the skills somewhat transfer. I also often use print() directly because to use a proper logger, I&#x27;d need to inject loggers with DI across several classes, import packages, when a simple print to stderr would work as well.
评论 #31618405 未加载
brundolfalmost 3 years ago
I do, mainly because of the cognitive overhead of setting up (and fixing when necessary) the extra tooling. Integrating my editor with whatever runs my code is just rarely a zero-effort experience<p>The exception is with JavaScript in a browser, since the browser is both the native environment where the code is running, <i>and</i> can show the highlighted code and let me set breakpoints. <i>However</i>, even then, more and more of my JS code takes the form of expressions, not procedural statements, and breakpoints just don&#x27;t help much with those. So in practice I still use them rarely
评论 #31614161 未加载
Beltalowdaalmost 3 years ago
I like printf-debugging because it&#x27;s usually the fastest and has the least mental overhead. Even with IDEs and integrated debugging I find there&#x27;s often a lot more overhead.<p>And when I do use a debugger I always just use it to inspect variables; quicker to just print those same variables: less steps, and especially works better if the same code will be run 10 times and I want to print those vars 10 times too.<p>I never found stepping over code useful in a debugger, and I tried to use it many times because surely it&#x27;s useful for <i>some</i>, but turns out it&#x27;s not for me.
FartyMcFarteralmost 3 years ago
Debugging is largely an effort to understand what&#x27;s going on inside a program&#x27;s execution.<p>Having the problem talk back to the programmer via prints&#x2F;logging is a perfectly sensible way to do this.<p>I have successfully used prints to fix tricky issues, in my opinion it is pure snobbery to deride this approach.
conradludgatealmost 3 years ago
In my case, I tend to leave debug level logs around my code. They are statically disabled in deploys so I can just turn on debug logs locally to see.<p>One thing I&#x27;ve noticed doing both .NET and Rust at work is that I often do use my Jetbrains debugger for C# but rarely do I use gdb or lldb for my Rust.<p>Rust feels a lot easier to stick a few more debug logs than it is to use the debugger. C# being VM based means it has a first class debugger that is invaluable to the language (I often joke that our C# code follows Debug Driven Development)
Morgawralmost 3 years ago
I work with a lot of different platforms&#x2F;languages&#x2F;programs, I&#x27;ve debugged code in various parts of the stack (kernel, firmware, virtualization, drivers, hardware devices in the lab, serial-connected devices, etc). Sometimes I just want to see if the code I am deploying is hitting the right areas, if I am entering the right function, if a certain variable is a certain value that I expect or why it is crashing. I don&#x27;t have time to learn the specifics of each language I use with each specific stack implementation that I&#x27;m working on (C for kernel and drivers, rust for virtualization infrastructure, C++ for some services, bash&#x2F;sh for some startup scripts and glue code, python for deployment scripts and tooling, etc). I just want to be able to print something, have it show up in the logs, and take it from there.<p>Print debugging just works fine and it&#x27;s a great aid, and I&#x27;ve seen most of my coworkers make use of it. Debuggers are great for more domain specific usages, people who work on a very specific project or service or application should definitely set up debuggers, but in my day to day work I probably switch between something like 10+ different projects weekly. Most of those also operate in such a distributed&#x2F;remote manner that it&#x27;s simply not possible to (easily at least) install a debugger with breakpoints and instrumentation. I&#x27;ve done my fair share of gdb debugging for performance profiling, and that&#x27;s fine, but that&#x27;s also a much more involved process that is not as simple as simply writing print(&quot;we got here!&quot;) all over the code :)
gnulinuxalmost 3 years ago
I am a proud print debugger. I think the key is to be sure you <i>know</i> how to debug using a debugger and know situations where that&#x27;ll be more efficient. If the trade-off is small, I think sticking to your preferred method is ok.<p>I write tons of fast unittests, so that I can get fast feedback from the system if anything unexpected happens. I think print debugging works quite well for this setup.
whatsakandralmost 3 years ago
I&#x27;ve found tests to be my new print debug. Too complicated of an internal state to get at what&#x27;s going on? Write a test. The failing test will tell you the output.
评论 #31617494 未加载
FatalLogicalmost 3 years ago
Please be aware that Paul Graham&#x27;s original tweet, which wouldn&#x27;t fit in the title, is:<p>&quot;I think the vast majority of developers still debug using print() statements.&quot;<p>— email from a founder
mtlmtlmtlmtlalmost 3 years ago
I&#x27;ve been working on a chess engine as a side project. Often, using print statements is the best way to chase down certain bugs where using a debugger isn&#x27;t particularly feasible.<p>E.g if there&#x27;s some bug in my search function resulting in weak play, but it only shows up at higher search depths for some reason. The search function is recursive, and the number of nodes visited grows approximately with sqrt(b^d) in the best case with ideal pruning. b is the branching factor(in chess this is ~30) and d is the search depth. That&#x27;s billions of stack frames to look at. The only way I&#x27;ve found of debugging these is through print statements and grep&#x2F;awk. As well as programming it to generate some statistics that may or may not be helpful. I&#x27;ve yet to find much use from debuggers.
demindiroalmost 3 years ago
I don&#x27;t think there is anything wrong with &quot;printf&quot; debugging. I actually use Rust&#x27;s dbg!()[0] macro quite often since it is quick to add and it gives me a good idea of the program&#x27;s flow of execution. Doing the equivalent with a debugger is much more tedious IMO since you need to set up all breakpoints and then either manually continue after each breakpoint or configure your debugger to print something at each point.<p>Usually when I use a debugger it&#x27;s after I already narrowed the problem down to a specific section and I need to view more state than dbg!() can practically show me.<p>[0]: <a href="https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;macro.dbg.html" rel="nofollow">https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;macro.dbg.html</a>
rasculalmost 3 years ago
Sometimes I&#x27;ll just log damn near everything with with debug! from rust&#x27;s log crate so if I need to debug I can just change the log level and I don&#x27;t need to remove it later (except for sensitive data).
kentonvalmost 3 years ago
If you have a fast, repeatable automated test that triggers the behavior you want to debug, then just about everything a debugger can do can be accomplished more easily by injecting code and re-running the test.
DeathArrowalmost 3 years ago
When I can run the stuff on my machine, I use a debugger because it&#x27;s much better to being able to step through, repeat execution of some sections, inspect values of any variables in the scope, change values of the variables.<p>But since some bugs will only appear in production, and I can&#x27;t deploy in production a development build, nor can I connect with ease a debugger to a process running in a Kubernetes pod, I have sometimes to use logging for debugging. Those cases are very rare, but they might still happen.
Findecanoralmost 3 years ago
In larger projects I have more commonly used logging-statements, each with its own log-level. Changing the log-level to log more is almost equivalent to using printf()s, only that you will get many more log-entries to wade through. But often that&#x27;s fine: it is more annoying to forget to log something than to log more than necessary.<p>There is typically also both compile-time and run-time log-levels, so that you can disable logging in release builds but still keep all in the source code.
beninsydneyalmost 3 years ago
I have always loved this method of debugging because printing messages outputs a chronological summary spanning the entire execution, and only relevant information is included.
jakebasilealmost 3 years ago
I&#x27;ll stop using `println` when it stops being so effective.
marginalia_nualmost 3 years ago
In the majority of cases, printf debugging is faster than debugger debugging. Debuggers can definitely help with some more gnarly bugs, but those bugs are rare.<p>Experienced developers aren&#x27;t marked by debugging one way or the other, but using the appropriate tool in the appropriate situation.<p>I also think printf debugging is one of those first to learn last to master sort of methods, as their utility is closely tied to the accuracy of your mental model of the code.
zh3almost 3 years ago
If building and running takes a second, printf is great (especially with inotifywait - as soon as a file is saved in the editor, trigger a build and run in a separate window). Even on programs approaching 100K LoC, ccache and make build the whole thing in less than a second.<p>On the other hand, if build&#x2F;run is a 15-minute cycle, a debugger makes a lot more sense; also for things like apparently random crashes that leave a coredump.
jasfialmost 3 years ago
One of the great things about print statements is that you can easily copy and paste them. Also searchable, as another poster has already commented on.
rramadassalmost 3 years ago
Very True.<p>The reason is that the Developer is <i>Reasoning</i> through the Code and <i>Playing Computer</i> simultaneously thus forcing him to make sure that both thought streams are &quot;synchronized&quot; at the stage of the debug print() line statements. It is this upfront work which goes into figuring out what the Developer intended vs. what the Computer really does that is so valuable for Code Comprehension.
quadcorealmost 3 years ago
Why would you debug by hand when you can use a computer? Meant in favor of print of course.<p>Thinking as I write it probably means it&#x27;s the print statement that should be improved for debugging if anything. Imagine a debugger that collect them, with the memory &#x2F; variables and stuff. Could also be turned into break points. Alternatively, could a newly developed terminal be coupled with a debugger like that?
slimalmost 3 years ago
I think debuggers are useful when your edit code -&gt; print result cycle is longer than a few seconds. When you need to compile for example.
dugmartinalmost 3 years ago
Ease of debugging for me peaked in the mid-90s when I did embedded system development using a 486 bond out emulator for GE. We had a couple in the lab (I think they cost $40,000 or so each) and they enabled breakpoints on really low level changes to the processor, down to changes to bus lines. Iirc it also allowed looking back in time on bus signals and memory values.
Vespasianalmost 3 years ago
I find myself using trace &#x2F; debug level logs quite extensively.<p>Not only does it add more comments to critical parts of the code. It also allows me to enable them briefly in production or staging if needed.<p>Actually debugging code happens rarely these days as it&#x27;s usually unnecessary.<p>PS: Copilot makes writing logs a breeze for me and taught me a trick or two about formatting.
YZFalmost 3 years ago
I recently found that this is a religious topic on the level of vim vs. emacs or tabs vs. spaces.<p>Some people rely heavily on debuggers for their day to day coding. I learnt to code without debuggers or IDEs - there weren&#x27;t any source level debuggers. Then embedded&#x2F;microcontrollers where the tooling existed but was very expensive (ICE etc.). I definitely used debuggers more at some point DOS&#x2F;Windows Borland and MSFT IDEs but mostly as time went by I found that I can usually just figure out the problem without needing a debugger or write correct code in the first place. If you&#x27;re working on a large distributed system your traditional debuggers don&#x27;t really help that much any more. But sure, there&#x27;s situations where you&#x27;d still use one.<p>I remember using watches like decades ago and then I just didn&#x27;t need to any more...<p>Whatever works I guess?
cyanydeezalmost 3 years ago
I do because chrome debugger doesn&#x27;t recognize that because I&#x27;m using. Bundler, I don&#x27;t care about the mess of layers between my code and my errors.<p>Everytime I try to step through, there&#x27;s all these arbitrary access layers that have to be hit.
评论 #31614342 未加载
评论 #31618303 未加载
CGamesPlayalmost 3 years ago
Printf debugging is to programming what spreadsheets are to analytics. Sure, you can make a better tool for some of the jobs, but it’s pretty much impossible to make a tool that is better against every facet of the incumbent.
pull_my_fingeralmost 3 years ago
I don&#x27;t understand the cleverness here. How else would you start debugging? If you&#x27;re not a IDE user, print is your first course of action. This is like gufawing about a doctor using a barium swallow or an x-ray.
bee_rideralmost 3 years ago
&quot;What else is there to use? The<p>print *, &#x27;var_name:&#x27;, var_name<p>statement is marshaled up perfectly by pretty much every MPI runtime. There just doesn&#x27;t exist a user-friendly MPI debugger,&quot; he said cunningham&#x27;s-law-ily.
phendrenad2almost 3 years ago
The only people surprised by this are non-developers. Founders are apparently very shocked that developers black terminals full of scrolling text and arcane key commands are used... to write printf() statements.
naniwadunialmost 3 years ago
Often they&#x27;re even right to do so!
kabdibalmost 3 years ago
If you are designing or implementing a language, <i>do the debugger first</i>. Well, very early, anyway.<p>Think of this as deep introspection into how well your design holds together. If you can&#x27;t write an effective debugger for the thing you&#x27;re hatching (or at least, an API and some good tests), then maybe you&#x27;re looking at a design flaw.<p>And in any event, you&#x27;ll have a debugger when you need one. And you <i>will</i> need one. This will probably speed up your development, and your users will hate you less.
评论 #31627128 未加载
cool-RRalmost 3 years ago
Shameless plug: PySnooper is a debugging tool for Python that lets you debug in a way that&#x27;s as easy as adding print statements, but gives you a lot more information automatically.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;cool-RR&#x2F;PySnooper&#x2F;" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;cool-RR&#x2F;PySnooper&#x2F;</a><p>HN thread: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=19717786" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=19717786</a>
gorgoileralmost 3 years ago
The vast majority of developers still debug by looking at, and then editing their source code.<p>Python matches up with this style perfectly. The next time you go into insert mode and feel like adding print(x), add a call to breakpoint() instead.<p><a href="https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;functions.html#breakpoint" rel="nofollow">https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;functions.html#breakpoint</a><p>`debugger;` does the same thing with browser JS engines.
ayalmost 3 years ago
Well placed and performant logging can be absolutely crucial:<p>- for a simple bug, it can allow to understand the root cause and fix the problem before even reproducing it<p>- for a tricky bug, it can help understand how to reproduce it, and verify that you are reproducing the correct one - and <i>then</i> comfortably explore it in a debugger.<p>Source: I had been troubleshooting both kinds of the above in networking gear for a decade as my professional occupation.
jl6almost 3 years ago
I wager most software projects start as small scale experiments where expedience rules. Printing to a console is perfectly good at this scale - and many such projects never make it beyond this scale. Tools like debuggers and structured logging can be introduced later, after it becomes clear that the project has ongoing value and the investment in extra tooling is worth it.
评论 #31627112 未加载
mbrodersenalmost 3 years ago
25+ years of professional experience here. I very rarely have to debug (because of extensive test suites). But when I do, I always use printf. It gives me the full power of the programming language to selectively detect and print the key information I need to reason about the system. It works great. I know how to use debuggers. I just choose not to.
nunezalmost 3 years ago
Ah, yes, printf(), the tool of choice when you have no tests, thousands upon thousands of lines of code, and millions of live wires
评论 #31627107 未加载
nomilkalmost 3 years ago
Ruby and R and both have amazing interactive debuggers: binding.pry and browser() respectively, and I use them all the time (never print statements). So I don&#x27;t understand the significance of PG&#x27;s tweet; do other languages have less-good debuggers, and hence people get stuck using print statements? Or have I missed his point entirely?
tester756almost 3 years ago
It&#x27;s probably matter of ecosystem, tooling<p>If it is weak, annoying, then people use prints<p>When using C# with Visual Studio and its strong debugging tools, why would you want use prints? (except specific cases that require it)<p>You can modify code at fly, jump between lines, evaluate expression at fly, use conditional break points<p>Why bother with some prints?
评论 #31618126 未加载
darepublicalmost 3 years ago
Debugger in chrome dev tools is easy enough though as I get older I find myself actually preferring console log, or similar strategies, again. Especially if the function in question get invoked multiple times, printing seems easier
评论 #31617597 未加载
brailsafealmost 3 years ago
It&#x27;s not that difficult to setup a debugger in most cases, but in javascript just write the word debugger wherever you want it to stop, and then open devtools. print statements can come in handy, but maybe once a year.
chronophylosalmost 3 years ago
I don&#x27;t know how to debug async code in Rust without print-statements &#x2F; log entries. If I step through the code it steps through the polls. Not to mention everything breaking if you need to talk to a server.
CSDudealmost 3 years ago
The debugger on IntelliJ is great, can do conditional breakpoints and calculate expressions on the fly, save previous expressions. That’s all I need from a debugger and mostly complements my print statements.
Fiahilalmost 3 years ago
Yes, because I didn&#x27;t find a way to attach a debugger on Databricks.
davidkuennenalmost 3 years ago
I do this and for me it&#x27;s the most efficient way most of the time.
eternityforestalmost 3 years ago
A language without excellent debugging is not a language I want to use at all.<p>Print statements are sometimes needed for embedded, but that&#x27;s probably my least favorite part of embedded.
s-xyzalmost 3 years ago
I think its fine to use print in some cases, e.g. quick debug. Google cloud function logging actually even translates it to an info record if I am not mistaking.
alfiedotwtfalmost 3 years ago
Relevant: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=28251896" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=28251896</a>
unixheroalmost 3 years ago
I do use print yes!
mkl95almost 3 years ago
I used to do that until I learned to stop worrying and love the IDE. I still use Emacs for a few tasks Jetbrains IDEs are not good at.
mseepgoodalmost 3 years ago
So? Use the tool that works best for you.
musicalealmost 3 years ago
Logging is incredibly useful and scalable - I&#x27;m not surprised that people still use it.
oumua_don17almost 3 years ago
I revert to print statements except when using Slime debugger.<p>Lisp live debugging is underrated.
lukegoalmost 3 years ago
These days I debug by doing &quot;data science&quot; on print statements.
pjmlpalmost 3 years ago
I only use print statements when left without any other option, and am thus forced to use them.<p>We have so advanced debuggers, OS telemetry, events, that plugging into print statements as first option reveals either lack of tooling or education.
评论 #31627093 未加载
评论 #31617488 未加载
评论 #31617675 未加载
bogotaalmost 3 years ago
… because it works and its faster most of the time.
elwellalmost 3 years ago
Emacs + Cider Debugger works great for Clojure.
brunojppbalmost 3 years ago
Yes, and that is fine.
devoutsalsaalmost 3 years ago
I often use…<p>1&#x2F;0<p>…or…<p>raise “potato”
评论 #31622938 未加载
ProfXponentalmost 3 years ago
I really cannot believe what I am reading in this thread.<p>It’s pretty trivial to setup a debugger in most IDE’s these days and share a config with your team.<p>Print logging falls flat on its face in async systems.<p>I feel like the ven diagram of people using text editors as a replacement for IDE’s and people doing print logging must be a circle.
评论 #31620211 未加载
评论 #31624949 未加载
评论 #31627190 未加载
评论 #31619239 未加载
praptakalmost 3 years ago
I certainly hope so!<p>Printf debugging makes you think about the program, build hypotheses and test them.<p>Stepping through the program is hit and miss.
oreallyalmost 3 years ago
That&#x27;s because many programming environments have not developed their debugging tools and people have accepted it as the mediocre norm.<p>If you&#x27;re ever tried an integrated IDE debugger for say debugging variables, I don&#x27;t think you can possibly say print debugging is better over one keystroke for setting a breakpoint, one keystroke for running the program to the breakpoint, and one gui window that just displays the local values.
评论 #31617858 未加载
bayonetzalmost 3 years ago
In this thread, people making all sorts of claims about print() debugging being better because of speed, efficiency, less overheard, “debuggers are too hard”, etc. on and on, but not actually providing evidence for their claim. For example, how do you know it’s faster for you? Less overheard by what comparison? Like did you give a debugger an equal and fair shot for some appreciable amount of time? I routinely probe these type of assertions from my coworkers about print()’s superiority and find that ~75% of the time, they’ve never given the debugger a fair trial or invested in understanding all it’s strengths and capabilities. ~25% of the time they’ve done a fair comparison and print() debugging is indeed the right choice for their context. Fine. Good for them! Every now and then someone takes me up on teaching them how to use a debugger effectively though and they are almost without exception, albeit begrudgingly, astounded at what they’ve been missing out on only using print().
评论 #31618102 未加载
评论 #31618056 未加载
评论 #31627039 未加载
评论 #31618069 未加载