Our case against debugging

For quite a long time, we have given the opinion that debugging was costly and not really productive (See Simon’s post Debugging process considered harmful back in 2003). Part of this position is the result of an experience that we like to do with our customers. We enter a room full of developers and we count the number of developers found "debugging" and not writing code. We have reproduced this experience several times, with various customers, and noticed that about 50% of project time is spent debugging and not producing code. And we are not even talking about the testing process here. Amazingly, we have recently seen a question on a LinkedIn group about the time spent in debugging, and 50% was the number mentioned as the first response to this thread by a developer. By the way, we need to congratulate the guy for pulling out this number as he is fully aware of where his time goes, which obviously is not the case for many developers.

So why is this so bad to spend half of developer bandwidth in debugging and how can we develop without debugging?

The main reason would be obvious to a financial guy. It is the "capex" versus "opex" difference. Debugging is an operational expense. Once you closed the debugger, all that you have learned vanishes and your time has been spent without any remaining value. As a comparison, imagine you have spent the same time putting appropriate tracing in relevant functions, outputting the key parameter values to a relevant file in a manner that can be reproduced and configured. You will get the same benefits as a developer to check that your program does what it should and detect potential mistakes. But at the same time, you will have prepared future analysis once the program evolves. Tracing is a capital expense.

Pushing the reasoning a bit further, one can easily understand that this is also a matter of team versus individual vision. The investment put in tracing will benefit to everybody while the debugging approach is an individual process that cannot easily be shared. As an example, I had a "magnetic resonance imaging" exam last month, and I was surprised and happy that all this exam was actually recorded and given to me on a CD. I am now able to share it with my usual doctor as well as any specialist that I would like to have a second look at the exam.

Similarly, it is also a matter of developer machine versus production environment. As computing gets more and more complex, with server-based and cloud-based infrastructure, as well as load-balancing or security constraints, the developer desktop – although simulating those infrastructures – will more and more differ from the real execution context. The risk of not being able to debug some scenarios is higher and tracing is often the only real option to understand what is happening. By the way, think about what is happening with airplanes. We have very powerful simulators that can simulate anything one can imagine. Still, we put black boxes in aircrafts to understand what happened under unpredicted circumstances. So tracing has to be done anyway.

Another more subtle collateral damage of debugging, for certain developers, is what we call stupidification. By hitting the F5 and F8 button convulsively trying to observe what the program does rather than control it, some developers tend to forget the sense of what they are doing, resulting in non-sense programming. Believe us, it is very hard to figure out why some instructions have been placed when they have been entered quite mechanically without any real thinking beyond the fact that this variable should have this value at this very specific step.

To be fair, it is worth mentioning that there are specific cases when debugging can be useful, but it should be the exception, not the rule. Also, we should recognize the progress made in debugging, especially the Intellitrace feature now available in Visual Studio Ultimate. It somehow addresses one of the issues made here, especially the ability to share a specific debugging scenario with the team. But it also tends to maintain the afterthought approach of debugging so this does not change our overall position at SoftFluent.

We hope that an Autotrace feature will appear someday within Visual Studio, so one could get with minimal effort the whole tracing deployed in the real production environment with appropriate configuration options. All the tracing infrastructure is already there and is pretty easy to leverage (see Using CLR 4 Event Tracing for Windows along with application ETW) but the development tool could propose us options to automate the tracing of the stack parameters and their values.

6 Responses to Our case against debugging

  1. Boris Bosnjak says:

    A thought provoking article! And the 50% figure sounds about right for an app that is in production, especially more mature apps.

    So tracing is something we should consider and embrace. Can you post a follow up blog entry on tracing best practices and strategies, based on your valuable experience?

    • softfluent says:

      Hi Boris,

      We will come back to this topic later as we want to alternatively cover different topics on the blog.

      As a start, you can have a look at this article http://www.softfluent.com/article/trace-server-.aspx

      And as per your detailed feedback on CodeFluent Entities product, I am sure you noticed that there are useful tracing functions in the Diagnostic namespace.

      Daniel

  2. Delton Phillips says:

    Very good article. I think we are wasting a lot of time debugging. I used to trace in Cobol and it was pretty effective, not sure why i’ve become a veg with a deep reliance on the debugger.

  3. I inherited some really bad code but it had to be modified to meet new requirements. Each modification tended to introduce more bugs. I was asked to get this code under control and improve its reliability, while adding functionality.

    I first created a set of regression tests . I could now keep the code OK by treating it as a black-box. It had to pass all the tests. The tests took time to run and check, but the approach kept the production system going as modifications were made. It had the added advantage that I did not have to understand the code. This was just as well because I didn’t at that time. :-)

    I renamed all poorly named items and inserted comments about what I understood each chunk of code was about. I then began to refactor small pieces of code and add trace outputs. Each separate piece of code had start and exit traces.

    All trace outputs followed a naming convention. Now I could now find where in the source code each trace came from. The logs were easier to follow because the first part of each message specified the trace’s location followed by a name and value.

    By this time the customer was seeing real progress as their system stabilised and debugging was speeded up.

    I finally knew enough about the behaviour of the system to start refactoring the structure of the overall solution and get it into a much more manageable state. By this time I could even give more reliable estimates as to how long changes might take.

    Finally, I was able to reflect back to the business what their business rules were and to help them debug their business processes. The tool used was StreamServe.

    Using tracing and some simple naming conventions helped massively.

    (I was just passing by but thought the above might help someone.)

  4. Pingback: Code instrumentation best practices « The SoftFluent Blog

  5. Pingback: Instrumentation du code : les bonnes pratiques « Le blog de SoftFluent France

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 103 other followers

%d bloggers like this: