Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo

Simple Debugging Techniques for Beginners

beginner debugging problem solving

  • Please log in to reply
6 replies to this topic

#1 0xFACEB004

0xFACEB004

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 625 posts
  • Location:Chicago
  • Programming Language:C, Java, C++, PHP, (Visual) Basic, JavaScript, Visual Basic .NET, Others
  • Learning:Assembly, Others

Posted 11 January 2014 - 08:59 PM

I've wanted to write a tutorial for quite some time now, and I'd planned to cover a topic a bit more advanced (thanks to Evan and BlackRabbit for all of their help on it), but after following some of the "help me!" threads here on CodeCall, as well as chasing down problems in my own code -- I've decided to write a simple beginners guide to figuring out why your program is not doing what it is supposed to do. This tutorial will only address logic errors and won't help with syntax or compile time errors.

 

These techniques should work in any language, so I will be using pseudo-code for my examples.

 

 

OK, let's start with the basics.

 

There are three things that have made my coding life easier when it comes to figuring out why things aren't going as planned:

1. Debugging statements

2. Basic understanding of how the program should flow

3. Breakpoints

 

 

Let's take a look at these one by one:

 

 

Debugging Statements:

 

Debugging statements are simply code that outputs information that you can use to trace what is happening in the program as it runs. This can be something as simple as:

// a program to output the age if the name returned is John


myName = readName() // get the value for name from readName function
age = 32

// here is our debugging statement, which will only be used during debugging.
// after debugging just comment it out.
// outputs the value of the name variable at this point.

// following line is for debugging
print myName 

if myName = "John"
    print age

The above statement will simply tell us the value of the variable 'myName'. By outputting the value at this point, firstly we can be sure that myName has a value (myName may have a value or it may be null at this point, the only way to know for sure is to check), and secondly what that value is. If nothing was outputted from our debugging statement for the variable 'myName', we can assume that something is not working properly in the function that is called to assign myName its value.

 

We can do a similar statement in the readName() function to trace what is happening there, as well. The next piece of code is what our readName() function might look like before adding a debugging statement:

// this function is called to read the name
// and return a string of the name that is read
string readName(){

    nameString = ""
    readInput() // reads the input from some file or other input
    return nameString

}

By examining this code you may be able to see what the problem is right away, but let's pretend that we can't figure out why are not getting the correct output. So, let's add a debugging statement to the function to see what happens when we enter this block of code:

// this function is called to read the name
// and return a string of the name that is read
string readName(){

    // for this part of our debugging we may want to add more than one statement,
    // one upon entering the code block so we know where we are in the code, and one before the
    // return statement to check the value of nameString before it is returned


    nameString = ""


    // the first statement will go here:
    // following code is for debugging
    print "In the readName() function"
    print " nameString variable = " nameString


    readInput() // reads the input from some file or other input


    // and the next debugging statement will be here:
    // following code is for debugging
    print "readInput() has returned"
    print "the value of nameString is now :" nameString
 

    // now return the value
    return nameString
}

If we were to code and run the above, our output would look like this:

In the readName() function
nameString variable = 
readInput() has returned
the value of nameString is now :

From this output we can clearly see that the value for nameString either did not change after readInput() returned or it is an unprintable character that cannot be shown on our screen. Either way this is not what we expected to happen, which brings us to number two:

 

 

Basic Understanding:

 

Basic understanding is simply having a basic idea of what the variables, the conditions that determine the programs flow, and the resulting output should or should not be. We know that nameString should have a value before it is returned, and one way to check our program flow is to hard code a value to see if it is returned like we expect it to.

 

This will change our code like so:

// this function is called to read the name
// and return a string of the name that is read
string readName(){

    // we hard code the value for nameString here
    nameString = "nameString Test1"


    // following code is for debugging
    print "In the readName() function"
    print " nameString variable = " nameString

  
    readInput() // reads the input from some file or other input

    // the value of nameString should change after readInput() is called to get a new value
   
    // following code is for debugging
    print "readInput() has returned"
    print "the value of nameString is now :" nameString
 
    // now return the value
    return nameString
}

Now when we run our code again we get the following output:

In the readName() function
nameString variable = nameString Test1
readInput() has returned
the value of nameString is now : nameString Test1
nameString Test1

As we can see, our hard coded value was outputted from out first debugging statement, and the same value was outputted from our second and third statements as well. This tells us that the value is being returned to the caller as we intended, and expected to happen, but we still don't know why the value of the variable nameString is not changed after readInput() is called...and we expected this variable to have a new value after the call. This is where breakpoints come in.

 

 

Breakpoints:

 

Breakpoints simply allow us to intentionally stop the program, or break it, to examine the variables and conditions at that point in the programs operation. In our above example, we know that the readName() function is called because our hard coded value for nameString was returned and printed out; so we know that that part of our program works as intended. We also know that our variables name and nameString are valid because we were able to print them. But we expected the value for nameString to change after the readInput() function was called and it didn't, so let's find out why!

 

First we'll want to determine where to set the breakpoint. Since we know that readName() is being called but is not changing the value of nameString as we expect, let's set our break point where we enter the readName() function.

 

* I am assuming that you already know how to set breakpoints (as every programmer should), if not, just Google it for your preferred IDE.

// this function is called to read the name
// and return a string of the name that is read
string readName(){ 

•  // we set our breakpoint to stop the program at this point so we can examine the following operations step by step

   nameString = "nameString Test1"


    // following code is for debugging
    print "In the readName() function"
    print " nameString variable = " nameString

  
    readInput() // reads the input from some file or other input

    // the value of nameString should change after readInput() is called to get a new value
   
    // following code is for debugging
    print "readInput() has returned"
    print "the value of nameString is now :" nameString
 
    // now return the value
    return nameString
}

When we run our code again, then the program will pause, allowing us to investigate the value of the variables at this point. We will see that nameString is null at this point since it has not be assigned a value yet, but we expect that. Next, (in Microsoft Visual Studio) we step over (F10) to get to the next statement in the function, which would be:

 nameString = "nameString Test1"

and checking our variables again, we find that the value of nameString has changed, just like we expected it to. So far, so good. We step over (F10) again, which would bring us to our debugging code -- which is not really a concern to us at this point, so we simply step over those two lines of code. But the next line of code IS important to us. It's the MOST important line of the code block regarding what we want to happen! This is where nameString should get its new value but it is not...and when readInput() is stepped over** the nameString variable does not change and still has the same value that we hard coded. Why?

 

** "Step into" (F11) could also be used to follow the code into the readInput() function to see what happens there, but for our purpose we'll just step over readInput() and check the variable changes.

 

 

 

If we go back to our code and examine what happens before and after readInput() is called we find where we hard coded a value for nameString, but what ever value that is returned from readInput() is NOT assigned to any variable! Could this be our problem? Let's make some changes to our code and find out.

// this function is called to read the name
// and return a string of the name that is read
string readName(){ 

•  // we set our breakpoint to stop the program at this point so we can examine the following operations step by step

   nameString = "nameString Test1"


    // following code is for debugging
    print "In the readName() function"
    print " nameString variable = " nameString

    
    // **** we change the following line so that nameString gets the returned value from readInput function and then test again ****
    nameString = readInput() // reads the input from some file or other input

    // the value of nameString should change after readInput() is called to get a new value
   
    // following code is for debugging
    print "readInput() has returned"
    print "the value of nameString is now :" nameString
 
    // now return the value
    return nameString
}

Now when run our code and step through, we see that nameString does indeed change after readInput() is called!

 

And for simplicity, let's assume that the name "John" is returned from readInput(), which would then be assigned to nameString, just we intended, and just as we expected. If we remove out breakpoint and run the code again, this would be output:

In the readName() function
nameString variable = nameString Test1
readInput() has returned
the value of nameString is now : John
John
32

This is exactly the output we expected. So now the only thing left to do is to go through the code and comment out all of our debugging statements so that they don't effect the output of our program. Once this is done, our final output will simply be:

32

and this is exactly what we expected the output to be.

 

 

In conclusion:

 

Some programmers (especially some of the old timers I have had the pleasure of learning from) don't like using debugging statements and say that using them is a waste of time, but for new programmers and/or students trying to work out the logic in their coding assignments, this can be a very valuable resource.

 

For larger projects it may become a bit harder to do, but for this I have taken to using log files -- simply creating a class to output the data from my debugging statements to a file; but it is the same useful information, and I can trace what happened when the code ran. And still using debugging statements to show me what is happening in my code as it is running -- I can see if something is not updating, or conditions are not being met, or variables are not getting the values that I expect them to get.

 

And knowing where something is going wrong in your code plays an invaluable role in finding what the cause of the problem is...and finding a solution to it.

 

 

I hope this tutorial helped you with your debugging. Happy coding!


Edited by KJGino, 13 January 2014 - 10:54 AM.

  • 1

                                                                                                                                                                            FACEB00K Likes this.


#2 WingedPanther73

WingedPanther73

    A spammer's worst nightmare

  • Moderator
  • 17757 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others

Posted 13 January 2014 - 07:54 AM

Nice little tutorial :)


  • 0

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

My MineCraft server site: http://banishedwings.enjin.com/


#3 0xFACEB004

0xFACEB004

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 625 posts
  • Location:Chicago
  • Programming Language:C, Java, C++, PHP, (Visual) Basic, JavaScript, Visual Basic .NET, Others
  • Learning:Assembly, Others

Posted 13 January 2014 - 10:49 AM

Nice little tutorial :)

 

Thanks WP!

 

Oh, and I wanted ask...was there ever a Fuzzy Logic part 3? I can't seem to find it, and I'm very interested to see what you did with it!


  • 0

                                                                                                                                                                            FACEB00K Likes this.


#4 WingedPanther73

WingedPanther73

    A spammer's worst nightmare

  • Moderator
  • 17757 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others

Posted 14 January 2014 - 06:07 AM

I switched to the C/C++ tutorials section for implementations:
http://forum.codecal...ng-a-fuzzy-set/
http://forum.codecal...-the-fuzzy-set/


  • 0

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

My MineCraft server site: http://banishedwings.enjin.com/


#5 0xFACEB004

0xFACEB004

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 625 posts
  • Location:Chicago
  • Programming Language:C, Java, C++, PHP, (Visual) Basic, JavaScript, Visual Basic .NET, Others
  • Learning:Assembly, Others

Posted 14 January 2014 - 11:07 AM

Thanks a lot! I am working on engine that compares multiple choices, and I may try using something like fuzzy logic.


  • 0

                                                                                                                                                                            FACEB00K Likes this.


#6 0xDEADBEEF

0xDEADBEEF

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 790 posts
  • Programming Language:C, Java, C++, C#, (Visual) Basic, Perl, Transact-SQL, Bash, Prolog, Others
  • Learning:Others

Posted 16 January 2014 - 04:38 AM

Very good :)


  • 0

Creating SEGFAULTs since 1995.


#7 0xFACEB004

0xFACEB004

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 625 posts
  • Location:Chicago
  • Programming Language:C, Java, C++, PHP, (Visual) Basic, JavaScript, Visual Basic .NET, Others
  • Learning:Assembly, Others

Posted 16 January 2014 - 10:13 AM

Thanks Evan, and thank you for all of the help you've offered in sorting out some of my issues  :thumbup:


  • 0

                                                                                                                                                                            FACEB00K Likes this.






Also tagged with one or more of these keywords: beginner, debugging, problem solving

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download