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.

The Debugging Mindset

246 pointsby jodooshiabout 8 years ago

15 comments

nostrademonsabout 8 years ago
The scientific-method-like &quot;general approach to debugging&quot; that the author describes in the last third of the paper works, but it&#x27;s pretty inefficient. The number of possible hypotheses that may cause an observed bug is very large; if you test each individually, you may have to go through many permutations, and you&#x27;re not systematically gathering data that may help you narrow the search space.<p>Rather, I&#x27;ve found &quot;divide and conquer&quot; debugging to be much more effective. You should know (based on your domain knowledge of the program) the rough sequence of operations between the input and output of your code; if you don&#x27;t, try single-stepping through it or adding log statements. Pick a point approximately halfway across that computation, and inspect (via debugger, println, or unit tests) the state of the program at that point. Does it match your mental model? If so, the bug is between there and the output; repeat the process on the latter half of the code. If not, the bug is between the input and your intermediate point; repeat the process on this subset. As an added benefit, you can often find and fix other, unrelated bugs that may not be symptomatic yet but are silently waiting to trigger strange results.<p>This process is O(log N) in the size of the code path, while the &quot;formulate hypothesis and test it&quot; approach is potentially combinatoric if the code interacts with itself.
评论 #14022035 未加载
评论 #14025937 未加载
评论 #14021451 未加载
评论 #14021452 未加载
评论 #14023101 未加载
评论 #14024200 未加载
评论 #14026576 未加载
评论 #14021557 未加载
cubanoabout 8 years ago
I have always used a step-debugger for debugging and personally find the process somewhat thrilling, especially when debugging other peoples code and learning all the tricks and techniques that they are using to get the jobs done.<p>I don&#x27;t know how much time and effort I have saved over the years using tricks I gleaned stepping through code written by people much smarter than I.<p>There is simply nothing that comes close to learning and debugging code line-by-line, examining variables and taking branches in real time. In fact, how people can debug large existing codebases <i>without</i> a debugger is beyond me.<p>Of course, nowadays in modern webdev it seems that most developers no longer use step-debuggers and, in general, want to rewrite the app in whatever stack will look best on their resume and&#x2F;or sound impressive in the pub or gym afterhours.<p>I long ago gave up poo-pooing the importance of social signalling within the young-ish developer community, something that really did not exist when I was 20-something as programmers had few choices about the stack.<p>I really love the jist of the OP, and agree that the misapplication of the programs mental model is the underlying cause of almost all bugs. This mental model is what I&#x27;m always trying to load fully into my brain as, IMO, true productivity occurs when I have it fully loaded and I am confident that I am covering all the edge conditions.<p><i>Debugging must not be an afterthought in educating; industry must stop insisting that bugs be interpreted as failures of individual programmers ... </i><p>Funny...I&#x27;ve really never separated debugging from developing as they always go hand in hand, and certainly have never thought that bugs signify &quot;failure&quot;. In fact, to me it represents progress...
评论 #14021290 未加载
评论 #14022028 未加载
评论 #14021292 未加载
评论 #14021801 未加载
评论 #14022241 未加载
评论 #14021308 未加载
评论 #14034585 未加载
评论 #14021167 未加载
评论 #14021275 未加载
评论 #14021401 未加载
评论 #14021976 未加载
edejongabout 8 years ago
Of course, Dijkstra had his view on it. I try to adhere to his position and prefer proof by type-checking over proof by single example.<p>&quot;A common approach to get a program correct is called &quot;debugging&quot; and when the most patent bugs have been found and removed one tries to raise the confidence level further by subjecting the program to numerous test cases. From the failures around us we can derive ample evidence that this approach is inadequate. To remedy the situation it has been suggested that what we really need are &quot;automatic test case generators&quot; by which the pieces of program to be validated can be exercised still more extensively. But will this really help? I don&#x27;t think so.&quot; [1]<p>Linus (used) to have a similar position [2]<p>Debugging hides the underlying architectural problem: to either communicate or abstract the algorithm in such a way that it can be understood by the programmer. If something needs debugging, not the bug needs to be fixed, but the architecture to understand the bug before debugging.<p>[1] Edsger Wybe Dijkstra - EWD303. <a href="https:&#x2F;&#x2F;www.cs.utexas.edu&#x2F;users&#x2F;EWD&#x2F;transcriptions&#x2F;EWD03xx&#x2F;EWD303.html" rel="nofollow">https:&#x2F;&#x2F;www.cs.utexas.edu&#x2F;users&#x2F;EWD&#x2F;transcriptions&#x2F;EWD03xx&#x2F;E...</a><p>[2] <a href="http:&#x2F;&#x2F;lwn.net&#x2F;2000&#x2F;0914&#x2F;a&#x2F;lt-debugger.php3" rel="nofollow">http:&#x2F;&#x2F;lwn.net&#x2F;2000&#x2F;0914&#x2F;a&#x2F;lt-debugger.php3</a>
评论 #14026959 未加载
jgrahamcabout 8 years ago
“<i>By June 1949, people had begun to realize that it was not so easy to get a program right as had at one time appeared. It was on one of my journeys between the EDSAC room and the punching equipment that the realization came over me with full force that a good part of the remainder of my life was going to be spent in finding errors in my own programs.</i>”<p><a href="https:&#x2F;&#x2F;research.swtch.com&#x2F;discover-debug" rel="nofollow">https:&#x2F;&#x2F;research.swtch.com&#x2F;discover-debug</a>
unexistanceabout 8 years ago
&quot;Everyone knows that debugging is twice as hard as writing a program in the first place. So if you&#x27;re as clever as you can be when you write it, how will you ever debug it?&quot;<p>Timeless<p>If you have to use &#x27;clever&#x27; hacks, the least you can do is justify it in the comment
评论 #14021134 未加载
评论 #14021120 未加载
theaeolistabout 8 years ago
Debugging an API, which may have obscure corner cases or usability quirks seems appropriate to me. &quot;Debugging&quot; an algorithm which has inherent logical flaws by attempting to patch it up with case-base reasoning and exceptions (logical, not runtime) is a road to disasters. I have seen too many devs trying to hill-climb their way out of a logical hole and the result is invariably a mess of a program which is still wrong.<p>Also, in case of concurrent and parallel code debugging is basically useless since realistic timing conditions are not reproduced.<p>I personally prefer logging, which gives a faster and more targeted trace of program behaviour than step debugging.
_nalplyabout 8 years ago
My secret sauce to debugging is formulating hypotheses about what went wrong then instrument the software to validate the hypotheses. By instrumenting I am talking about manipulating running software to give me information.<p>Sometimes the manipulating step is made unnecessarily hard, and the trick is to force the hand. I see myself an inquisitor of software and use programmatic torture to get what I want to know. That&#x27;s the central attitude to debugging.<p>The devil is in the details, there are many possibilities to get information: using a runtime debugger, insert output statements, read the logs, use LD_PRELOAD, use strace, and so on.
sleepychuabout 8 years ago
My favorite debugging trick (when faced with an &#x27;impossible&#x27; bug) is to state my assumptions, it&#x27;s usually clear when they&#x27;re all laid out which ones are conflicting.
评论 #14021875 未加载
评论 #14021854 未加载
评论 #14025050 未加载
sharpercoderabout 8 years ago
&gt;Are the arguments to memcpy in the order of source, destination, length; or are they destination, source, length? Is strstr haystack, needle; or is it needle, haystack? Many individuals develop a habit of consulting references (such as system manuals) as soon as the question comes up.<p>I&#x27;ve always found this particular problem solveable by allowing programming languages having syntax in the form of<p><pre><code> public void CopyFrom(int address)To(int address)OfSize(long size) { &#x2F;&#x2F; impl } </code></pre> instead of<p><pre><code> Copy(int fromAddress, int toAddress, long size) </code></pre> Are there good reasons why languages haven&#x27;t adopted this syntactic nicety?
评论 #14022923 未加载
评论 #14021358 未加载
评论 #14021342 未加载
评论 #14021362 未加载
评论 #14023971 未加载
评论 #14021359 未加载
sn9about 8 years ago
Udacity actually has a course on systematic debugging taught by the creator of DDD.<p>The course covers the importance of the scientific method and hypothesis testing, divide and conquer approaches, etc.
noyedaabout 8 years ago
Nice article. Thought I&#x27;d note something:<p>&gt; Software developers spend 35-50 percent of their time validating and debugging software.1<p>This is a strong claim, so I looked at the cited source, given the unfortunate experience of having seen many strong claims backed by weak underlying data.<p>&gt; The research phase will predominantly comprise of short interviews with approximately 10 to 12 organisations that compile code on the LINUX operating environment. These organisations will also fill in the Cambridge Venture Project (CVP) survey to help quantify how much time they spend debugging with and without RDBs. Broader research in the form of the CVP survey with potential users of reversible debuggers will be conducted to gain insights on how much time is currently spent debugging.<p>Further down:<p>&gt;49.9% Programming time spent debugging<i></i><p>&gt; <i></i>According to 54 questionnaire responses to the CVP survey and 11 interviews, based on the question ‘Of the time spent programming, what percentage of your time is spent on the following: (1)fixing bugs (2)making code work (3)designing code (4) writing code.’ (1) and (2) then were grouped as debugging.<p>While this might be indicative of a widespread phenomena, it doesn&#x27;t seem to be enough evidence to support the factual and strong claim of the first sentence in the ACM article. There certainly isn&#x27;t enough information in the cited source alone to decide (and given that, is this really sufficient as a source?).<p>Perhaps I missed further evidence?<p>That being said, I won&#x27;t throw the baby out with the bathwater. Debugging is clearly a time sink in industry, regardless of what the actual percentage is.<p>I enjoyed this piece overall. I was previously unfamiliar with some of these terms -- specifically incremental vs. entity mindsets -- and it shed some light on work issues I&#x27;ve seen (coincidentally in the debugging technology space). Being someone with an incremental mindset and having worked for someone with an unjustified entity mindset, I found the environment suffered from almost all the problems (and more) you described associated with the latter mindset. Granted, this is anecdotal.<p>I quite strongly agree that improving the process and mindset behind problem-solving results in a significant improvement to specific skills like debugging software. It&#x27;s refreshing to see an article like this instead of the many others hyperfocused on specific, less-abstract techniques (and widely-applicable abstract techniques&#x2F;processes are the most effective use of one&#x27;s learning time).
评论 #14026368 未加载
filleokusabout 8 years ago
I think it&#x27;s fascinating to see how my friends at university (who previously had no programming experience) have started to &quot;get&quot; debugging and the benefits of using something like a step-debugger. It took several programming courses before they started to actually debug the code instead of just reading it and trying to figure out what happens. I mean, reading the code is also an integral part of debugging, but often times they said things like &quot;fooBar _should_ be true, so we _should_ enter this conditional&quot;. Then it of course turned out that fooBar was in fact not true because of some logic bug or something they didn&#x27;t even consider.
评论 #14022533 未加载
评论 #14021600 未加载
mattmanserabout 8 years ago
I personally found this to be a poor article on the subject. There&#x27;s very little actual content about debugging, he spent more time talking about theories of intelligence than debugging.<p>I&#x27;ve recently been thinking about this, thinking about making a course. It&#x27;s my personal experience that his approach is flawed. Fundamentally, step one is not develop a theory. That is the worst thing you can do, it can waste a lot of time. I still sometimes guess what the problem is, but all I really use that for today is where to <i>look</i> and that&#x27;s sometimes a waste of my time as I skipped step 1.<p>Step 1 is recreate it. No theorizing, no thinking, no faffing around. Can you recreate the bug exactly? If you can&#x27;t, find out why. Talk to the bug reporter, find out what they were doing, this is a people skill you need to learn as a programmer. Maybe you need access to the live data to see the state an object is in. There&#x27;s only a tiny percentage of bugs (usually race conditions) that can&#x27;t easily be recreated. If you can&#x27;t recreate it, that&#x27;s when you turn to logging to try and catch the conditions to recreate it, but logging is the last thing you should try and I rarely ever have to add it (we&#x27;re talking 1% of bugs). I often see junior programmers littering code with log statements when trying to debug, I feel this is a bad method, but can understand the temptation, especially when they don&#x27;t really understand what the code is doing (an understandable position I was in in my earlier days).<p>Step 2 is isolate it. If the code is simple and it&#x27;s obviously one method, no further work needed. If the code is complex, you need to really isolate the exact problem. Say you&#x27;ve got the wrong value displaying for a basket total, where is that coming from? Is it not updating, or is the total function the problem? Isolate the exact step in the process that&#x27;s going wrong. Sometimes it&#x27;s hard to isolate and logging is needed again, but same advice as before, logging is a rare necessity.<p>Step 3 is make it easy to run a recreation. If you can run it in 10 secs or less, that&#x27;s great. If it&#x27;s one method of a complex web call, make a test endpoint that only calls that method that&#x27;s failing and exactly recreates the conditions. Then you can run it quickly without all the cruft. In an extreme case, this can be taking the code completely out of the context and putting it in a tiny standalone app.<p>Step 4 is read + understand the code. Is there an obvious logic bug? Don&#x27;t jump to conclusions. Still don&#x27;t get what&#x27;s going on? Step through the code, breakpoints. Understand what&#x27;s going wrong. Breakpoints and stepping is fine, inspecting variables, etc.<p>Step 5 is fix it. This should be fairly simple now. This is also the time to think about the future. Is this part of the code a constant headache? Is it buggy because it&#x27;s over-complicated? It might need a bit of a refactor to make sure this doesn&#x27;t happen again. This is a judgement call, unnecessary refactors are expensive, might even introduce new bugs, but over-complicated code will lead to more bugs. It not being written in your favourite style is generally not a legitimate reason to refactor.<p>Step 6 is testing the fix, recreating the conditions from step 1. Don&#x27;t rely on QA if you have them. Ensure you&#x27;ve done your job.<p>(Step 7 get rid of your logging statements + test it again! You just changed the code)<p>Now you can skip steps, be far less formal about it. Sometimes it&#x27;s obvious. Sometimes it&#x27;s hard and you may need to iterate over 4&#x2F;5&#x2F;6 a few times. But never, ever skip steps 1 + 6. Recreate it. Test your fix. Because if you skip those steps, and you &quot;fix&quot; it, you don&#x27;t actually know it&#x27;s fixed.
评论 #14024299 未加载
评论 #14022382 未加载
评论 #14022048 未加载
评论 #14024717 未加载
rdtscabout 8 years ago
To make debugging easier you have to pick tools (languages, IDEs, methodologies) that make it easier. In other words you optimize for debugging.<p>For example, I find Erlang code very easy to debug. There are few reasons for that:<p>* Built-in runtime tracing is easy. Can remsh into a VM node and trace any function at runtime.<p>* Functional style with immutable data and variables make it easy to figure what is changing in the code. Because of immutability the state is always updated explicitly. That makes it much easier to understand what is happening for me that figuring it out than having a class inheritance hierarchy with methods overrides and such in an OO language<p>* Code hot-patching makes it easier to test and iterate to zoom on in a bug. With care it can be done in production. You see strange failure you never saw before and which you had an extra log statement in there? That&#x27;s easily done.<p>* Language is simple and self-consistent. That means there is less chance someone used some obscure new feature I haven&#x27;t heard about. This is a bit like C vs C++. C is very simple at the language level. You can still have hairy code with triple pointers, funky dispatch tables with Duff&#x27;s Device thrown in there but at least you can read through it. Looking at C++ code I sometimes couldn&#x27;t even parse what was happening because of a language feature (so they overrode the operator some place, and using a templates, ...). Or someone created a macro and then everything is more interesting all of a sudden.<p>* Process heap isolation. When something happens with one process, I know for a fact that it hasn&#x27;t scribbled on memory of other processes. I can restart that process if needed and test my hypothesis of what I think is wrong, often without affecting the rest of the system (even while it is running in production).<p>* Sane concurrency primitives: Having the ability to create hundreds of thousands of processes with isolated memory often mean a smaller impedance mismatch with your business code so you have less total code to write. The less code your write, the less code you have to debug.<p>Anyway the point being, debugging should be a trade-off in picking your tools. People don&#x27;t think about it much and focus on other things first. But it will be something that over time will make a tremendous difference.<p>&gt; Virtual machine-based languages, interpreted languages, and languages with runtime environments encourage users to view the execution environment as a black box. The goal here is to make programming easier by reducing the scope of the mental model the programmer must maintain. When bugs occur in these execution environments, you&#x27;re left with a complete gap in understanding.<p>It can be the opposite as well. Having a VM with good tracing and debugging facilities is very useful. Often you can do things wouldn&#x27;t be able to with just plain compiled code.
jerianasmithabout 8 years ago
Investigating is essentially a space particular term for critical thinking. Bugs are depicted as word problems.Since mental models are approximations, they are in some cases inaccurate, prompting unusual conduct in programming when it is created on top of flawed suspicions.