This article will give you step-by-step introduction to debug Windows Forms application run-time error using C#.
Figure: 1 - Example in run-time mode.
Introduction
How often do you hear from your pear, "I'm busy debugging my code"? Well, as I can see debugging and code development goes hand-in-hand for every developer. Although debugging is becoming easier and innovative every passing release of VS 2005; beginner level developers still find it challenging. Here is my take on debugging 101. In this article, I'll show you, a simple step-by-step tutorial to find bug and go one step ahead to become a code warrior!
I assume the reader has the basic understanding of the Visual Studio (VS) 2005 IDE. You should also comfortable writing code with C#.
What is Debugging?
Well, to understand what is debugging, you've to know what a bug is! If I can put it in a simple word, bug is result of code went wrong during your development. So, what does bug do? Well, simple it produces error. You know what happens when an error is produce; therefore, debugging is process to remove such bugs and prevent errors.
A quality of the application is determined with the amount of debugging efforts spent on it. No wonder nine out of ten times we build project in debug mode. A truth in developers life is no matter how much care is taken bugs does get into code. Even the most experienced developer can introduce a bug by doing silliest of silly mistake. I'd say nothing to worry; with a strong debugging support built into VS IDE, we can easily tackle the most notorious bug.
Different types of Errors!
Now we know bug produce error! So, what are the different types of errors? Well, let's divide them into the following three categories:
Design time error, I'd say most "friendly" errors of all. The simple reason is most of them can be fixed without much hassle. VS IDE feature Intellisense plays a big role to fix this error. Run time error, here you go, welcome to the world of panicking. Run time errors are real bad if they crash your application during demo session.
Third in list is logical error. Boy, here you basically gradate from state of panicking to hair pulling. On rather lighter note, at this time you also think of banging your head on your favorite keyboard or tossing the box out of the window.
Bugs which produce logical errors are nasty. As you can see, complier doesn't complaint on them. You'll also wont get any run time error; however, the result you are expecting, don't show up the same. In such scenarios debugger comes most handy. Let's look at the following example:
Imagine you are calculating average sales for each month. The formula is simple, "average sales per month = total sales / 12". Now at some point in your code instead of 12 you are dividing it by 13. So the result is not correct. To find out this 13 in code and replacing with 12, that is what debugger will help you with.
To demonstrate the debug technique we need to create a bug first. This is one of rare moments where you are deliberately creating a bug. So, have fun. Creating run time bug is not a big deal. You can see many situations which can result in run time error. For example, how about "Divided by Zero"? Or Array index out of the range error?
Let's go ahead and create a simple application which will produce a table of two and store the result in an array of ten subscripts. We'll introduce the error in loop, in which we read from array and display the table using multiline Textbox control. Please see
Figure 2, one button will produce the table and another one will result in a run time error.
Let's create a Windows Application Project
If VS 2005 IDE is not already started, then you can launch the IDE by clicking on windows Start button -> All programs -> Microsoft Visual Studio 2005 -> click on icon Microsoft Visual Studio 2005. You may have others ways to lunch the IDE, such as clicking it on your desktop and so on.
Please do the following steps to create a Windows Application Project:
-
Click on menu File -> New -> Project... or you can press the hot key Ctrl + Shift + N (please see Figure 2).
-
From New Project dialog box select -> Visual C# -> Windows.
-
From Templates select -> Windows Application.
-
Please give the name to the application; I've called the project as "WinDebug101". You may choose a different location for storing the application files according to your preference. Please see Figure 2 for illustration of the naming process.
-
Click on OK button to finish the process. VS 2005 will create a new project and more or less your project should look like Figure 3.
Figure: 2 - Process to create New Windows Application Project.
Figure: 3 - View of newly created project.
Most of you'll see something similar to what the Figure 3 looks like; however, depends on your current VS 2005 IDE settings, you might see some toolbox hidden or floating. Anyway, you should see the blank Form1 created for you because of new project. Please refer to VS2005 help to customize the look and feel of IDE.
Tip: You can always access the menu View Ø Toolbox or press Ctrl + Alt + X, to make Toolbox window visible. To get the maximum space on designer surface, you may like to use Auto Hide feature of Toolboxes.
Let's set properties of Form1 according to Table 1. In case if property toolbox is not visible in IDE, you may hit F4 key to make it visible. Pease make sure to select Form1 by before applying changes to properties using property toolbox.
Table 1. Properties of Form1
Property |
Value |
Text |
Windows Forms debugging 101 |
Size |
300, 300 |
Let's add controls to newly created Form1
The example is simple. As you can see in Figure 1, we'll have one RichTextBox control to enter and format text. We've two buttons to use for formatting the text and rest two to interact with Database.
We need the following controls on Form1:
Let's start by dragging and dropping above mentioned controls on the Form1.
You can add controls to Form1 in two different ways. First method is to double click on the control; second method is to drag and drop the needed control on the form. The second method gives you more control as it let you drop control on your exact preferred location.
Please make sure your Form1 looks like something similar to Figure 4.
Figure: 4 - Form1 designer surface after adding controls.
Please change the properties of controls on the form according to Table 2. Properties can be change by selecting the control and using properties toolbox. Please see Figure 5 for graphical illustration of the process.
Figure: 5 - Changing properties of controls on Form1.
Table 2. Properties setup of controls on Form1
Control |
Property |
Value |
textBox1 |
Multiline |
True |
Button1 |
Text |
Table with no Bug |
Button2 |
Text |
Table with Bug |
Please make sure after the change of properties on Form1, your form should look similar to Figure 6.
Figure: 6 - Controls on Form1 after changing the properties.
Let's write some C# code to bring life to Form1
Please make sure code behind Form1 looks like the following:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WinDebug101
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string[] TableOfTwo = new string[10];
int i;
// loop to calculate the table
for (i = 0; i < 10; i++)
{
// 2 x 1 = 2...
TableOfTwo[i] = "2 x " + Convert.ToString(i + 1) + " = " +
Convert.ToString(2 * (i + 1));
}
// loop to display the table
for (i = 0; i < 10; i++)
{
// 2 x 1 = 2...
textBox1.Text = @textBox1.Text + TableOfTwo[i] + "\r\n";
}
}
private void button2_Click(object sender, EventArgs e)
{
string[] TableOfTwo = new string[10];
int i;
// loop to calculate the table
for (i = 0; i < 10; i++)
{
// 2 x 1 = 2...
TableOfTwo[i] = "2 x " + Convert.ToString(i + 1) + " = " +
Convert.ToString(2 * (i + 1));
}
// loop to display the table
for (i = 0; i < 11; i++)
{
// 2 x 1 = 2...
textBox1.Text = @textBox1.Text + TableOfTwo[i] + "\r\n";
}
}
}
}
Code Analysis
Well, as you can see, the code is simple loop to produce table of two. First loop does the calculation and store result in array. The second loop reads through the array and displays the result in multilane enabled textbox. The code inside button1_click event is the "good" code. This code will not create any error and go on to calculate and display the table output.
The code inside button2_click event is the "bad" code. This code will produce a run time error because of the bug we introduce. So, can you spot the bug? Well, if you see the type of error, it is easy to find where is out bug. If you see Figure 1, it says error: Index was outside the bound of the array. This means the loop which display the result is trying to access array outside its limits.
So, the only difference between code behind both button is:
// loop to display the table
for (i = 0; i < 11; i++)
{
// 2 x 1 = 2...
textBox1.Text = @textBox1.Text + TableOfTwo[i] + "\r\n";
}
As soon we try to access 11th physical array element, this bug causes program to halt and results in runtime error. You may also notice that I'm not using Try...Catch purposely here to display the error.
Let's build and run the example
Let's build the project. You can build a project in several different ways, if you just have one project in solution; building solution and project are the same. You can click on small Green Play button on main toolbox or hit F5 on keyboard to start the application in run time. Please also make sure to build using Debug mode. Please see Figure 7.
Figure: 7 - Project Build.
If all goes well, then you should be able to run the application. Let's click on "Table with no Bug" button. Because of this action you will see textbox populate with table of 2. Now, let's click on "Table with Bug" button. Aha, there you go, instead of result, the VS 2005 IDE comes up with a complaint of run time error! Your run time error screen should look similar to the run time error shown in Figure 1.
Let's debug our run-time error
As you can see in Figure 1, when a run-time error occur the execution of program halts where it encounter the error. In our example the execution stops while running loop which displays the table, here is the code snippet:
// loop to display the table
for (i = 0; i < 11; i++)
{
// 2 x 1 = 2...
textBox1.Text = @textBox1.Text + TableOfTwo[i] + "\r\n";
}
When program stops at link inside the loop, what does it means to you as a developer? Well, it is obvious to say, this line has some functionality which is violating something! So, what do you think, what other information is given to developer by IDE to help get rid of the bug?
When an error happens the code throws "exception". This is our first channel of information as to what happened. In our example the type of exception is: "IndexOutOfRangeException". So what does it mean? Well, as u can see since we're using array and type of exception is prompting, something is wrong with index range. I would like to mention this, debugging is an ongoing learning process. The more the errors you will experience first hand the better debugging skills you'll get.
Apart from type of exception, Visual Studio IDE also provides different feedback windows to developer which can help to quickly resolve the error. On such feedback is Locals window. As you can see in Figure 8, we can see the current content of array TableOfTwo[] here. Most of the time just by analyzing the content of variable, one easily spots the bug.
Figure: 8 - Feedback Windows in Debug mode.
Watch window is another such feedback which you can use to specifically query value of any given object. Let's say you like to see the content of 4th physical element of the array. You can do so by switching to Watch window (in this case Watch1) and type TableOfTwo[3] and press enter. You will see that value column will show up with "2 x 4 = 8". Please see Figure 9 for graphical illustration.
Figure: 9 - Feedback Watch window in action.
In many cases we need to go step-by-step till we encounter the error. This way we get better know how of what exactly happen. This process can be done easily while in debug mode. First step is to decide about code location were we need the execution to pause. This way we can take control and move step-by-step till we hit the error.
This step is commonly referred as setting up break point. We can setup break point in two ways. First, to click on left most gray area of code line. Second method is to select the code line and press F9 key. Once break point is set, a Red bullet mark appear on line, suggesting when execution process sees this, it must stop. In our example since we like to go each step in loop to see at which point code is breaking. We've to setup break point at the loop entry code. Please see Figure 10 for the breakpoint setup.
Figure: 10 - Setting up break point.
Once the breakpoint is setup properly, you can step through the code in following ways:
-
Step Into Debug -> Step Into (F11 key).
-
Step Over Debug -> Step Over (F10 key).
-
Step Out Debug -> Step Out (Shift + F11 key)
As you can see in Figure 11, we've three ways to step through the code. Step Into means execute the currant line of code and move to next. If next line is call to another method then "Yellow" code pointer move to that code segment. Step Over means "Yellow" pointer move to the next line in the current code segment without stepping into any local methods that might be called by the current line. Finally, Step Out means current method to complete and the execution should halt on the next line of the method that called the current method.
If you like the program execution to continue as normal then you select Debug -> Step Over or hit F5 key. You can also start and stop debug by selecting appropriate command from Debug menu.
Figure: 11 - Stepping through in debug mode.
You can also access all these features with help of Debug Toolbar. Please see Figure 12 for graphical illustration.
Figure: 12 - Debug Toolbar.
Conclusion
As you can see, how simple it is to use powerful debug feature of Visual Studio IDE. With this article I tried to introduce the debugging process. I hope this article will help especially the beginner level audience to get started with debug process. Thank you for reading; as always I'm looking for comments and suggestion. Feel free to drop them at [email protected].