Skip to main content
GameDev.net gamedev.net
🔒 Locked

a good way to debug

Started by staticVoid2 Sep 10, 2008 at 12:31 PM 5 replies 1.3k views
Original Post
staticVoid2
staticVoid2
hi, my debugging of code is slowly turning into a nightmare, my method this time around is to use windows MessageBox(); function for every message I need displayed, this has advantages - mainly it stops the execution of the program so you know where something has gone wrong, but when you are debugging a lot of data it can be quite boring having to click OK 1000+ times. I'm looking for a way I can pass a certain output handler to a module of code for it to use for debugging, so that in certain parts of code all I need to call is one function for outputting text. but I don't wan't the overhead of all these function calls in release mode, I've though of a couple of ways: C++ interface:


class IOutputHandler
{
public:
   virtual void printf(const char*, ...) = 0;
};

and just pass an instance of this to a function, class etc. for it to use for displaying text, but it still has the function call overhead and a check to see if the pointer is null. templates:



class std_debug
{
public:
   void printf(const char* format, ...)
   {
      ...
   }
} _std_debug;

template <class T>
void function(T debug)
{
   debug.printf("", ...);
}


function(_std_debug);

still has the function call overhead (unless you create a class whos printf() does nothing then the compiler may? optimize the function call away). is there any better way of doing this?
stonemetal
stonemetal
If you haven't detected an error why would you print things out for debugging purposes? If there is an error and you need to print something out printing is about 1000 times slower than a function call so who cares about function call overhead?
godecho
godecho
Are you using this mechanism for logging or debugging? If you're trying to debug, a good debugger I think would be a much better choice.

If you're logging- even at the code level, the standard already provides a nice output object already: ostream. If you're concerned about the performance of logging in release mode, you might be logging too much, or just thinking about things in the wrong way.
Servant of the Lord
Servant of the Lord
As far as I know, most people use simple #defines to display things only when in debug mode. This is, at least, what's been taught to me in more than one book.
#ifdef DEBUG_MODE   #define PrintDebugMessage(x) printf(x)#else   #define PrintDebugMessage(x) { }#endif

If you are debugging, you can have #define DEBUG_MODE at the top of your header file, and if you are in release mode, you can have that line commented out.

You then use PrintDebugMessage("A error occured! Function: int MyBuggyFunction()") to log messages, and when debugging it'll output the messages as printf() normally would, and when not debugging, the code isn't compiled into your project at all.

You could ofcourse not use printf() and use a different function. For instance, maybe you want your code full of assert()s when not in release mode, or maybe you want to output messages to a file. (Use std::ofstream for this)
Antheus
Antheus
Quote:
but it still has the function call overhead
Quote:
is there any better way of doing this?


Let's do some critical thinking here:
- Our logging function writes on average 50 characters (to console, screen, etc).
- If our logging is disabled, it will result in virtual function call overhead that does a NOP

Hypothesis: NOP version is inefficient

In order for NOP to show up in profiler, it needs to run about 0.1% of the time. Let's assume that this test causes a cache miss (200 cycle penalty).

On a 3Ghz CPU, taking into consideration 200 cycle cost, this would mean that 0.1% time means the logging handler is invoked 15,000 times per second. Again, this is 0.1% CPU load.

If we now enable logging, then we will be writing 15,000 strings per second. Is this even remotely a realistic case?

How many are you actually generating per second? If it's less than 15,000, then the miss penalty is a non-factor.


IMHO: If overhead of a NOP handler is indeed a performance issue - then don't do any logging at all (eliminate calls via macros or typedefs). Hopefully we are discussing performance of release build.
godecho
godecho
Quote:
Original post by Servant of the Lord
As far as I know, most people use simple #defines to display things only when in debug mode. This is, at least, what's been taught to me in more than one book.
#ifdef DEBUG_MODE   #define PrintDebugMessage(x) printf(x)#else   #define PrintDebugMessage(x) { }#endif

If you are debugging, you can have #define DEBUG_MODE at the top of your header file, and if you are in release mode, you can have that line commented out.


Most compilers already define something like _DEBUG when you're compiling in debug mode.

http://msdn.microsoft.com/en-us/library/b0084kay(VS.71).aspx

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.