What Debugging Is and How to Debug: A Beginners Guide

We get exceptions. Usually it is best to test our applications before submitting them to markets or other platforms for users. Debugging is one of those options to test your applications. As the name suggests, debugging means “to debug” (What?) the application. It is a process in which framework problems and other logical errors are removed from the errors.

As a software developer you might know that there are usually the following three types of errors:

  1. Syntax error
  2. Runtime error
  3. Logical error

Syntax errors and runtime errors are two types of errors that can be shown to the developer by the framework or compiler (first one). So the developer just must check what went wrong and what to do to fix it. However the third type of error cannot be checked by a compiler. Logic is something you make up. You need to write the correct algorithm to make it work. If there is some kind of problem, you need to check your algorithm once again to ensure that it is a correct algorithm. Logical errors do not generate any error when compiling the source code. They also don't notify the user about incorrect results. A common example would be:

  1. int Remainder(int a, int b)  
  2. {  
  3.       // provided b is not zero  
  4.   
  5.       return a / b;  
  6. }  

Indeed, the developer wanted to get the remainder, but used the division operator. The source code would compile and would provide results, the wrong results.

Debugging helps us in finding such errors and solving them to get the correct answer and solution. This option is provided in every IDE (Visual Studio, Android Studio, Eclipse and others that you have tried) for developers to debug their applications.

How to debug

Now you might also want to understand how to debug your applications. Well, that is pretty simple. I have also mentioned above that (nearly) all of the IDEs provide tools to debug your application. I have used Eclipse, Visual Studio and Android Studio. They all have provide (similar) tools to debug the applications and see how things are done.

The idea of “how things are done” is helpful when solving logic errors. A point to note here is that debugging is not only helpful in solving logic errors, it is also sometimes helpful when removing the runtime errors such as the most famous “NullReferenceException”. (For more on the NullReferenceException you can read this other article of mine to understand what it is. Why it is generated and how to solve it.) Syntax errors need to be resolved before the object-code can even be generated. So that leaves the debugging method applicable to run-time and logic errors only.

The procedure to debug generally depends on the type of error you are trying to debug. So let me clarify the two types of debugging processes. However, the actual process is similar. You start and end up in the same way, it is just your internal process that is different for both, 1. Run-time error, 2. Logical error.

Process

In every IDE, an option to set breakpoints is included. Breakpoints are a few steps in your code where the IDE notifies you when the code execution reaches that place (or point). You are then allowed to check the application's memory consumption, variables (including their “at that time” values). At this stage you can see what the state of the application is and how it should behave. You can also check what type of variables (with the values) are sent to this block and how they are being used or manipulated. This would further guide you in fixing the problem.

Run-time error debugging

For example, if you stumbled upon a DivideByZeroException. Then you can add a breakpoint to your function and execute step-by-step, one-by-one each statement and look into how your code gets a variable with zero (or is the user ing the value to be zero) and so on. This type is the Run-time error debugging. DivideByZeroExceptions are generated at run-time when the code executes. That is why you usually would encounter this error when running the application only.

This type of debugging is somewhat easy, because it doesn't require a lot of searching for errors. The framework that you are using would throw an exception and you (if you are having more than beginner-level experience) would easily know that the program is telling you to fix this problem at this location. And then you can easily add the patch to fix the problem.

Logical error debugging

Debugging a logical error is somewhat of a tough task because they cannot be found easily. You need to run through each and every statement to determine Where did things actually mess up? Sometimes it can take 5 – 10 minutes, sometimes it can take an hour, depending on the complexity of the logic or algorithm being designed.

Let us see an example of an “Age calculating” algorithm. Have a look at the following C# code.

// Assume dateOfBirth is coming from user having valid dateTime expression

  1. var age = (DateTime.Now - dateOfBirth).Days / 365;  
The age variable would hold the correct data only if the logic is applied correctly. We know that our logic is correct. But it is not! We know that 365 is the number of days in a year, but what we don't know is that we need to round up the overhead number of hours in a Leap year after 4 years. So if the preceding code is run, it is not guaranteed to give the correct answer to every input. It might have at least a greater than 10% chance of errors. If processed under debugging tools, we would find that using 365.25 as the divisor is the correct way to find the age of a user using a DateTime object. So now the following code would run correctly and would not have as much of an error ratio as the preceding code had. (However there still might be a chance of errors!)
  1. var age = (DateTime.Now - dateOfBirth).Days / 365.25;  

Now when you use it, it will display the correct outur for the provided input.

Note: The preceding example has a physical significance, I wrote the age calculation algorithm that gave me my age to be 20 years (when I was 19.5 or something years old).

Points of interest

Now let us wind things up. A few of things mentioned in this article are:

  1. Debugging is a process in which bugs (mainly logical or runtime) are removed from the application.

  2. (Nearly) every IDE supports debugging tools.

    1. Breakpoints.
    2. Debugger (in which the application runs,  vshost.exe can be an example for Visual Studio geeks).
    3. Profiling tools, memory management, variable information and other tools required to alter the state of application and to check what is going on under the hood.

  3. Run-time errors are easily understandable and solvable because the underlying framework tells the developer what went wrong. So (if the developer has some understanding of the framework then) he can remove the chances of problems occurring again.

  4. Logical errors take more time. Because they depend on the complexity of the logic being solved. They can be removed only if the algorithm is fully understood and how it should be written in the language.

    See the examples above for more.

That's all for now folk! :-) I hope it helped some of you.


Similar Articles