6 Steps to Debugging Code

So you are relatively new to software development and you are presented with one of the most difficult bugs to resolve. What do you do? Where do you begin to look?

In my experience, when this occurs less seasoned developers will do one of the following:

  1. immediately give you a possible source of the problem
  2. immediately write more code to attempt to identity the problem
  3. Agree to have a solution by the end of the week and make NO progress.

Why is this?

One thing I always remind my colleagues is that software development is a science, even though there are some who feel this is an art. Let me repeat this, software development is a science. So, in the field of science, how do we solve problems? Do you remember the “scientific method”? Developers should utilize the scientific method to solve software problems. The 6 steps of the scientific method can be utilized to ease the pain of debugging and increase your likelihood of success.

1. Ask a question

When presented with a bug you MUST ask questions to get a clear understanding of the problem. Within this phase you want to understand all aspects of the problem. In most cases, problems that exist in software are not random. Therefore your goal in this phase of the problem solving process is to remove the random nature of the problem and find the predictable nature of it. Below are few key questions that will assist you in your findings:

  1. When does it occur?
  2. What behavior are you experiencing?
  3. Can you consistently reproduce the error?
  4. Can you recreate this issue in a different environment?

2. Do background research

Take each answer to the questions asked and analyze or verify the information given. Be sure to evaluate the environment or any other specifics that will allow you to make better assumptions. This information should be used to assist you in formulating your hypothesis.

3. Create a Hypothesis

Your hypothesis is what you think the root problem is based on your understanding. At this point, you should fully understand the problem and make an educated guess to where the source of your problem may originate from. This can only be done by leveraging your research to read through the code and better understanding what is being executed.

4. Test your Hypothesis

At this point you will understand all the details of this problem. Take your hypothesis and find the areas within your code that support you hypothesis and begin to put breakpoints in the appropriate places in code. By running the code within the debugger you can view the execution of the code and inspect variable values as well as the execution paths.

5. Analyze your Test Results

Based on the results of your test and debug sessions, review the information that was gathered and the execution path of your test. Determine if your test cases are valid.

6. Accept or Reject your Hypothesis (Draw your Conclusion)

At this point you should fully understand the problem and should be able to accept or reject your root cause hypothesis. If your hypothesis has been proven, begin formulating a plan to fix the bug. If you hypothesis is rejected, start over at step 1 until you are able to find the root cause of your bug.


How to reduce an elephant of Technical Debt

What is Technical Debt?

In order to fully understand the impact of technical debt, we must first have a full understanding of the cost of software maintenance. One of the most neglected areas of the software development life cycle is maintenance. As defined by wikipedia.com, software maintenance is the modification of a software product after delivery to correct faults, to improve performance or other attributes, or to adapt the product to a modified environment. Over the years the proportion of software maintenance cost of a product has increased from approximately 70% to over 90%. Annual software maintenance cost in the United States has been estimated to be more than $70 billion (Sutherland, 1995; Edelstein, 1993). The cost in software maintenance consists of various types which include perfective maintenance, enhancements, time for developers to understand the code, and legacy systems. Each of these types of maintenance contributes to a complex problem called Technical Debt.

In the December 2009 issue of MSDN Magazine David Laribee wrote an article entitled “Using Agile Techniques to Pay Back Technical Debt”. This article explains techniques on analyzing and making a case for reducing “technical debt”. Technical debt is the expensive costly code that is hard to maintain and error prone. This type of code kills productivity and is difficult to maintain. The question that the article answers is “should we fix technical debt”. One reason to fix technical debt is the long term cost benefit. Test-Driven designs will have a higher initial cost but over time the cost will level out where in a rapid untested coding design the initial cost is low but over time the cost will grow exponentially. The following steps should be taken to formulate a plan to sell to the management team:

  1. identify where the debt is
  2. build a business case and get a consensus on the priority
  3. fix debt with proven tactics
  4. find additional debt and repeat

After a plan has been formulated and accepted, there is still an extremely hard question that needs to be answered. How do you reduce an elephant of Technical Debt?

How to reduce an elephant of Technical Debt?

So the million dollar question is “How do you eat an elephant?” The answer: One bite at a time. In order to take on an elephant amount of technical debt you must first determine the best way to simplify or divide the problem into manageable pieces. The following steps will help you reduce technical debt:

  1. Identify the code that will give you the greatest return
  2. Introduce shape
  3. Create unit test for the changes made
Identify the code that will give you the greatest return

When identifying the change that will give you the greatest return look for the following signs:

  1. Code that seems to produce the most defects
  2. Code that is frequently used by users
  3. Code that “looks” ugly

After identifying high return candidates, you must evaluate the impact and estimate the return. Once the high return candidate is identified you must begin reducing technical debt by introducing shape to your code.

Introduce shape

There are several ways to introduction shape into your system.  The first thing you should do is get a complete understanding of your code and how they should communicate within the system.  This understanding will allow you to clearly understand how system components will communicate and it will reveal system coupling.  Using your new found understanding of the system, begin organizing your code into namespaces named after the layers of your architecture.  As you begin to introduce shape and/or create layers, begin to define rules that dictate which layers are allowed to interact with each other.  After successfully introducing shape to your system, you can begin to further solidify your design by creating new projects based on your namespaces.  This will allow you to enforce the new shape by controlling the project references.  While making these dramatic changes to your system, you must take precautions to protect against the introduction of new defects.  Therefore, you must create unit test to exercise the areas that have been changed.

Create unit test for the changes made

There are many unit test frameworks available that will help you to create test to prevent the introduction of new defects.  As you make changes to introduce shape, you should also create a group of unit test.  If there are any failed test, you must act immediately to address the defect.  Not addressing these issue immediately you will reduce the confidence of the management team and stakeholders.

Asking the obvious: "I want cartoony…"

As a software consultant, I sometimes have interesting experiences. I have seen good software, bad software and even software that should not be working based on its current state. Consultants are often brought in to be the “expert” of any given matter. Are consultants really that smart? If you ask me I would say yes but I am a bit partial. The reality is that consultants are perceived to be smarter because we are given the opportunity to exercise the correct way to ask questions. In this post, I would like to illustrate techniques that could result in receiving information better due to the effectiveness of asking questions properly.

I recently had an opportunity to work on a relatively new project for one of our clients. We came on the project to assist with the architecture and user experience of the client’s application. What I witnessed spoke volumes to me when the UX consultant was told that they wanted their UI to be “cartoony”. The meeting continued on for at least an hour then the UX consultant asked “what is cartoony”. There was a long pause and the response to the consultant was, “you know, cartoony”. There was another long pause and the consultant continued to look perplexed then the client stated, “you know, no one has ever asked me that question”. The client proceeded to explain his definition of cartoony and it was nothing like his employees envisioned or described to us.
So, why was the obvious never asked? Were they embarrassed? Was there a previous attempt to explain this and his employees still had no idea of the expectation and did not to continue to probe? Or were they over thinking what they were being asked?

I decided to take a deeper look at the art of asking questions and came across a good book titled “The Art of Asking: Ask Better Questions, Get Better Answers” by T. J. Fadem. One thing that stood out to me was the author’s rules for asking questions. The author called these rules the “Ten Basic Rules for Asking Questions” which are:
1. Be direct
2. Make eye contact
3. Use plain language
4. Use simple sentence structure
5. Be brief
6. Maintain focus on the subject at hand
7. Make certain the purpose of the question is clear
8. The question must be appropriate for the situation and the person
9. The manner of asking should reflect the intent
10. Know what to do with the answer

With this said, are consultants smarter or do we have the luxury to ask any question because we are the outsiders? I don’t think consultants are smarter, we just spend a majority of our work day asking questions, therefore we have mastered the skill of asking the obvious.