Jump to content
  • Advertisement
Sign in to follow this  
pix0l

How do YOU debug?

This topic is 4781 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I've been spending an awful lot of time debugging my code lately and I'm considering doing things differently if this trend continues. I use Visual C++ 6.0 and it has a built in debugger but I never really use it. What I do usually is strategically insert code in suspected problem areas and print out variable values or whatever to a console window. This method works pretty good for me. I do things this way mostly because I never really took the time to learn the debugger. I was always too busy learning how to program and I got used to printing values to a console window. I'm curious what the rest of you like to do and why? Can any of you give me some good reasons to consider using the debugger as opposed to my method?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by pix0l
I'm curious what the rest of you like to do and why? Can any of you give me some good reasons to consider using the debugger as opposed to my method?


While having trace functionality is good there are always going to be problems that are easier to address using the debugger. I include logging in most functionality of of programs but only where it's logical to do so. This is usually in places where I want to monitor the results of checks, the chaging of states, and other activity. The logger I use can be activate or deactived based on function name, class name, file, group, or component category.

Altough I have a robust logger it's typically only used to determine resuls before, during, and after specific operations. Once I have that information I set a few breakpoints, set the breakpoint conditions (if necessary), and fire up the debugger. The conditions are set to that the breakpoint only triggers if a specific condition exists (hence the need for the 'before the bug' results). Using the debugger really isn't all that difficult and there are only a few keystrokes you need to remember. After using the debugger for a while the hotkeys become second nature.


Debuggers can be very powerful tools for locating - especially with features like Edit and Continue which allows you to change the source code while you are debugging, compile, and continue with the debugging session. This is FAR easier than run/watch logs/test/exit/runagain/watchmorelogs/yaddayaddayadda. I definitely recommend using it.

Share this post


Link to post
Share on other sites
Quote:
Original post by pix0l
I'm curious what the rest of you like to do and why? Can any of you give me some good reasons to consider using the debugger as opposed to my method?


Here's one reason: Stepping. You can check your program's execution line by line.

Here's another reason: Backtraces. With any decent debugger, you can get a backtrace which shows exactly where a program crashed or threw an exception. Although this might not directly correspond to the original bug/problem, it at least shows what blew up, and then you can ask the question "why did it blow up".

Here's yet another reason: No recompile. To add a check in potentially buggy code requires adding checks, recompiling, running the program up to the point where you think it might be crashing, and then getting the resutls. This can waste a lot of time, especially if it can potentially take a lot of time to get to your error state.

There are sometimes benifits to writing code for the aid of debugging, but these usually differ from simply printing out a variable. I'm thinking of things like unit tests. Although I do not follow the practice of creating a test first, I do create such a test before I even attempt to compile that which is being created.

The idea is that you create a test that checks multiple aspects of a class (for example) to make sure everything is still running sanely. If part of the test fails, you know you've broken something.

The simplest unit tests can be made with a simple assert. Here's an example testing the classes in my endian_integers.hh header file:

#include <industry/endian_integers.hh>

#include <algorithm>
#include <cassert>

int main () {
using namespace industry;

unsigned int big_value = 0x1234ABCD;
unsigned int little_value = 0x1234ABCD;
unsigned char big_rep[] = { 0x12 , 0x34 , 0xAB , 0xCD };
unsigned char little_rep[] = { 0xCD , 0xAB , 0x34 , 0x12 };

big_endian_integer< 4 > big ( big_value );
little_endian_integer< 4 > little ( little_value );

assert( big == 0x1234ABCD );
assert( little == 0x1234ABCD );

big = little;
little = big;

assert( big == 0x1234ABCD );
assert( little == 0x1234ABCD );

big = big_value;
little = little_value;

assert( big == 0x1234ABCD );
assert( little == 0x1234ABCD );

for ( unsigned int i = 0 ; i < 4 ; ++i ) assert( big == big_rep );
for ( unsigned int i = 0 ; i < 4 ; ++i ) assert( little == little_rep );

assert( std::equal( big.begin() , big.end() , big_rep ) );
assert( std::equal( little.begin() , little.end() , little_rep ) );
assert( std::equal( big.rbegin() , big.rend() , little_rep ) );
assert( std::equal( little.rbegin() , little.rend() , big_rep ) );
}



If any of the assertions fail, or the test fails to compile, then I know I've introduced a problem. The only one that failed on me so far was what "for ( unsigned int i = 0 ; i < 4 ; ++i ) assert( little == little_rep );" previously was, and that was because the test was miswritten (I typeoed 0x34 as 0x24. This made me realize I probably shouldn't be copying myself as well, and I then created *_rep[]).

As I start tackling more complex problems, I'll probably get into using the Boost Test Library.

Share this post


Link to post
Share on other sites
How can you even program without using the debugger you must be some kind of madman...

Seriously though learn how to use it. It will save you lots of time.

Share this post


Link to post
Share on other sites
Hi, your method is quite OK if your programs are not very complicated and if you know where there may be a bug in your code.
But if you are using printf(...) or OutputDebugString(..) or sth like that in big application than you will have to delete all of this for release version. Besides this methods only tells you that your variable is not what it supposed to be so it only partially helps you.
First, with debugger you can move instruction by instruction or you can set "breakpoints" where debugger will stop and allows you to go manually. This is very helpfull if you have some part of code (for example complicated algorithm) and know that something is wrong but don't know exacly what. When you debug you see all variables values, you can change them during debugging, add "watch" variables and even see processor registers and change them (It helped me recently when I had some problems with library written for Intel compiler)
I think you should try it, it's not very complicated, just learn how to set breakpoints, use watch window, and step into/step over keys.

Share this post


Link to post
Share on other sites
Quote:
Original post by pix0l
Hi,

I've been spending an awful lot of time debugging my code lately and I'm considering doing things differently if this trend continues. I use Visual C++ 6.0 and it has a built in debugger but I never really use it. What I do usually is strategically insert code in suspected problem areas and print out variable values or whatever to a console window. This method works pretty good for me. I do things this way mostly because I never really took the time to learn the debugger. I was always too busy learning how to program and I got used to printing values to a console window.

I'm curious what the rest of you like to do and why? Can any of you give me some good reasons to consider using the debugger as opposed to my method?

Oh good lord, I used to do that before I learned the debugger. Take my advice, set aside some time to learn it, soon. It's far far easier to find bugs this way and a hell of a lot quicker too.

Share this post


Link to post
Share on other sites
Definitely learn to use the debugger.

That said, efficient low tech alternative debugging techniques are still helpful sometimes. Like debugging a problem that only happens on a particular computer which has no port to connect a kernel debugger, and only manifests itself on a fresh windows install over a reboot. [bawling]

Share this post


Link to post
Share on other sites
A debugger can definitely help. I use gdb all the time. It can easily give you an idea of just where in your code you need to look. I also have a log that will print error messages if, for example, a texture was being loaded, but the file couldn't be opened.

Seriously, it takes too long time to recompile everything to add checks like that everywhere.

Share this post


Link to post
Share on other sites
Quote:
Original post by Helter Skelter
Quote:
Original post by pix0l
I'm curious what the rest of you like to do and why? Can any of you give me some good reasons to consider using the debugger as opposed to my method?


While having trace functionality is good there are always going to be problems that are easier to address using the debugger. I include logging in most functionality of of programs but only where it's logical to do so. This is usually in places where I want to monitor the results of checks, the chaging of states, and other activity. The logger I use can be activate or deactived based on function name, class name, file, group, or component category.

Altough I have a robust logger it's typically only used to determine resuls before, during, and after specific operations. Once I have that information I set a few breakpoints, set the breakpoint conditions (if necessary), and fire up the debugger. The conditions are set to that the breakpoint only triggers if a specific condition exists (hence the need for the 'before the bug' results). Using the debugger really isn't all that difficult and there are only a few keystrokes you need to remember. After using the debugger for a while the hotkeys become second nature.


Debuggers can be very powerful tools for locating - especially with features like Edit and Continue which allows you to change the source code while you are debugging, compile, and continue with the debugging session. This is FAR easier than run/watch logs/test/exit/runagain/watchmorelogs/yaddayaddayadda. I definitely recommend using it.


How do you use logging code in visual c++6? I looked for it in tools and under debug, but havnt found anything like you mentioned

Share this post


Link to post
Share on other sites
Quote:
Original post by The C modest god
How do you use logging code in visual c++6? I looked for it in tools and under debug, but havnt found anything like you mentioned


Ehh.. Just log something to file.
C example:

int teh_int=666;
float teh_float=13;
char buf[1337]; // 1337 buffer
int l=sprintf(buf,"teh_int=%d, teh_float=%f",teh_int,teh_float); // Real men don't care about buffer overflows
FILE * f=fopen("LOGGGGGGG.txt","w"); // Real men don't do error checking
fwrite(buf,1,l,f);
// Real men don't close file handles

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!