Learn to Debug Your Own Code!

Learning basic debugging techniques is a requirement in order to even think about becoming a successful software developer. While the topic of debugging has had entire books written about it, these simple techniques should be considered mandatory for developers.

In the past ten plus years, my site partner Robbe Morris and I have personally read and answered many thousands of forum posts on eggheadcafe.com. We welcome questions, and we're also fortunate to have a cadre of expert repeat forum participants who are here to help answer your questions. In fact, we think forum participation is so important that instead of giving out recognition points and "badges" we pay out real cash.

I particularly enjoy responding to questions because it keeps me sharp - it makes me think and helps me to refine my writing technique to become ever more clear and concise - a skill which I believe should not be lost on software developers of any platform.

But over this period of time, one begins to see a pattern (or, should I say, an antipattern) -- in these forum posts.

One of the patterns I see is the one where somebody makes a forum post and lists an exception message with some sample code. Often when reading over their forum post you can see immediately that during their development process, they had no earthly idea where in their code this exception was thrown or why. They are, in effect, "lost" in their own code! This leads me to my first recommendation:

Develop with exception wrappers. You can remove them later

During development, try to get in the habit of wrapping any code block that could possibly throw an exception in a try / catch block. In the catch block, you can set a breakpoint and examine the thrown exception via Intellisense in the Visual Studio IDE.  An example:

try
{
// your hot shot code here that you are sure is perfect!
}
catch (Exception ex)
{
// set a breakpoint on the next line!
  System.Diagnostics.Debug.WriteLine (ex.ToString()); // this will show up in the Output window
}

That's so simple that it should become an afterthought -- you ought not to even have to think about adding this bit of extra code. Why? Because if your code causes a boo-boo, a breakpoint at the Debug.WriteLine statement will enable you to mouse over and look at the exception's Message and StackTrace properties in debug mode (as well as the InnerException property - very important, if there is one) and instantly be able to tell exactly at what line in your code the exception was thrown, and exactly what it was. So instead of mindlessly posting questions on forums because you didn't take the time to do this, you instead have now empowered yourself to become a better, more efficient developer! You'll not only save time and frustration, but each time this happens you will begin to learn more and more about the .NET Framework, it's idiosyncracies, and it's behavior. I know this seems awfully basic, but you would be surprised at the percentage of people who have never learned how to do it, or even - how to turn on line numbers in the code window!

Unwind multiple expression statements into separate lines of code

Another slightly less common problem I see is that developers have a line of code with multiple chained method calls or nested method calls in it. When an exception is thrown, how can you tell which statement or expression is the culprit -- because it is all on one line of code! During development, it's a good idea to get into the habit of unwinding your statements, method calls or expressions, each on a separate line. Then if an exception is thrown, it becomes much easier to find out what happened and where.


Learn how to break on the exact point where an exception is thrown

Often when dealing with code that has more than one "level", an exception may be thrown but it is not actually caught or handled until farther up the call stack. This can make it very difficult to discern exactly where the exception was thrown and makes accurate debugging very difficult. You can change this behavior by telling the Visual Studio debugger to break at the exact line of code where an exception is originally thrown:

At the top Visual Studio menubar, choose "Debug" and then "Exceptions". Check the box that says "Thrown" under the Common Language Runtime Exceptions.



You can also debug into third party assemblies for which you do not have source code by going to Debug/ Options and unchecking the "Just My Code" box.  Various DebuggerStepThrough and other attributes can be placed at key blocks of code to control whether the debugger will step over or break on a particular block of code.

Use Project References during the development process

Setting Project references to other projects in your Solution is preferable to setting hard references to compiled assemblies. This allows the developer to "debug through" - following the code path from one assembly to the next and being able to examine values at various stages in the development process. It makes it easier to find and fix errors in your code. If you have the source code, bring the project into the solution and set your references to the project - not the built assembly from the project.

Learn to program in a type-safe manner.

This is particularly important for developers who choose to use Visual Basic.NET. Option Strict and Option Explicit should ALWAYS be turned on. This puts you at least close to the league of the C# developer, who doesn't have to worry about things like this because if they make a code mistake, their code simply will not compile at all.

Unfortunately, VB.NET is much more forgiving (by design)- so if you want to be a pro you'll need to bring it into line with other languages. Another thing VB.NET developers need to understand is that not all languages are case-insensitive (most are not). So if you're developing a class library that may be consumed by a C# developer, you want to be extra careful not to set up ambiguities in the casing of your properties and methods. Setting the CLSCompliant attribute can help:

VB.NET:
<Assembly: CLSCompliant(True)>

<CLSCompliant(True)> Public Class MyCompliantClass
   Public Sub ChangeValue(value As UInt32)
   End Sub

   Public Shared Sub Main()
      Dim i As Integer = 2
     Console.WriteLine(i)
   End Sub  
End Class


The above code generates the following Visual Basic compiler warning:

warning BC40028: Type of parameter 'value' is not CLS-compliant.


CLS compliant code must be exposed in the following if you use this attribute:

Definitions of your public classes.
Definitions of the public members of public classes, and of members accessible to derived classes (family access).
Parameters and return types of public methods of public classes, and of methods accessible to derived classes.

I hope these ideas are helpful to you as you go about your development adventures.

By Peter Bromberg   Popularity  (2372 Views)