Tips and Tricks for Debugging in C++

C++ Debugging Tips and Tricks

By: Vijendra Kumar H.

Some of these are Microsoft specific.

  1.  __FILE__ and __LINE__ can be used for logging the file name and the line number of the source code.

  2. E.g. You can use these macros in printf statement like
      printf (“Error in file %s at line %d\n”, __FILE__, __LINE__);
  1. While writing the code, sometimes, we may not know the exact implementation at that time. Common practice is putting a comment there as

  2. “//needs to be implemented”.
    But, while handling very big projects, there are chances that we may forget to fill these gaps.  Here is a nice way of handling these kinds of situations.  We can make use of “#pragma message (string)”.  Just define the following macro in a common file

    #define __STR2__(x) #x
    #define __STR1__(x) __STR2__(x)
    #define IMPLEMENT(mesgStr) "Pending work: " mesgStr \
                " at " __FILE__ "(" __STR1__(__LINE__) ")"

    And at the places mentioned above, you can call this macro as
    #pragma message(IMPLEMENT("Your message"))
    When you do a build (or compile), you will get this message as the compiler output.  Even incase if you are using make files, this trick will work.
     

  3.  If you are carrying out the debugging process using an IDE, then you can make use of the following function.

  4. OutputDebugString("testing message");
    This function sends the specified string to the debugger for display. If the application has no debugger and the system debugger is not active, OutputDebugString does nothing.
     
  5. If you are not using the integrated debugger, you can make use of message boxes to display certain information. These message boxes serve both as Watch window and as breakpoint.

  6. Here is an example:
      char tempArr [100];
      wsprintf(tempArr, "Calling function ErrFunc(x=%d,y=%d )", x, y );
      AfxMessageBox ( tempArr );
      ErrFunc ( x, y );
       
  7. When using MFC functions, the TRACE macros can be used. The TRACE macros generate debugging information by sending it to the afxDunp object, which is a predefined object of the MFC class CDumpContext. There is an entire series of TRACE macros. The TRACE0 macro accepts a single text string. The TRACE1 macro accepts a text string and one parameter, the TRACE2 macro accepts a text string and two parameters, and so on. The TRACE macros can only be used when compiling the program in debug mode. When debug mode is off, the TRACE macros are ignored.

  8. E.g.   TRACE2 ( "Calling function ErrFunc ( x = %d, y = %d )", x, y );
       ErrFunc ( x, y );
     
  9. The ASSERT macro can be used to interrupt the program execution when a certain expression evaluates to false. This is, for example, useful to check parameter values for errors. The macro can only be used in debugging mode. Otherwise it is ignored.

  10. E.g.   void ErrFunc ( int x, int y )
    {
           ASSERT ( x >= 0 && y < 100 );
      .....
    }
     
  11. The ASSERT_VALID macro can be used to verify if a pointer points to a valid object. The macro can only be used in debugging mode. Otherwise it is ignored.

  12. E.g.   CSampleDoc *pDoc;
              pDoc = GetDocument ();
              ASSERT_VALID ( pDoc );
     
  13. The CObject class has a member function called Dump (). This function dumps the contents of an object to the debug output window. To use this function for a user defined class, you have to define this function. For example as follows

  14. E.g.
      #idfef _DEBUG
      void CSampleDoc :: Dump ( CDumpContext& dc ) const
      {
        CDocument::Dump ( dc );
        dc << "m_xPos = " << m_xPos << endl;
        dc << "m_yPos = " << m_yPos << endl;
      }
      #endif

     
  15. Conditional Breakpoints - If you want to break at a specific point when a value is true, place the breakpoint at the appropriate line, select it in the checklist at the bottom of the Breakpoints dialog, then from the Location tab, select "Condition". There you can set the same things as on the data tab, plus the number of times you want the debugger to skip a breakpoint before it actually stops.
  1. Visual C++ v6.0 is shipped with a very good integrated debugger, but it has even more features than is documented in the online help files. You can make use of these features and make your own programming a little more efficient………like Automatic expansion of structures etc…… http://www.codeguru.com/debug/autoexp.shtml