Debugging Tips

team bbl


Defensive programming, error reporting, and other coding techniques can only go so faryou also need a debugger that lets you step through your code examining variables and tells you exactly where your program is misbehaving or has crashed. So, you will need to maintain at least two configurations of your applicationa debug version and a release version. The debug version will contain more error checking, will have compiler optimizations switched off, and will contain the source file, line, and other debug information that the debugger needs. The preprocessor symbol __WXDEBUG__ will always be defined in debug mode, and you can test for this when you need to write debug-only code. Some functions, such as wxLogDebug, will be removed in release mode anyway, reducing the need to test for this symbol.

A surprising number of users will try to get away without using a debugger, but the effort expended in getting to know your tools will pay off. On Windows, Visual C++ comes with a very good debugger; if using GCC on Windows or Unix, you can use the basic GDB package (from a command line or editor), and there is a selection of IDEs that use GDB but present a more friendly GUI to the debugger. For information on these, see Appendix E, "Third-Party Tools for wxWidgets."

wxWidgets allows multiple configurations to be used simultaneously. On Windows, you can pass BUILD=debug or BUILD=release to the wxWidgets library makefile, or when using configure, you configure and build in two or more separate directories, passing --enable-debug or --disable-debug. Some IDEs don't allow multiple configurations of your application to be maintained simultaneously without changing settings and recompiling in debug mode and then changing the settings back and recompiling in release modefor obvious reasons, avoid such tools!

Debugging X11 Errors

Rarely, your wxGTK application might crash with X11 errors, and the program will immediately exit without giving you a stack trace. This makes it very hard to find where the error occurred. In this case, you need to set an error handler, as the following code shows.

[View full width]

#if defined(__WXGTK__) #include <X11/Xlib.h> typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *); XErrorHandlerFunc gs_pfnXErrorHandler = 0; int wxXErrorHandler(Display *display, XErrorEvent *error) { if (error->error_code) { char buf[64]; XGetErrorText (display, error->error_code, buf, 63); printf ("** X11 error in wxWidgets for GTK+: %s\n serial %ld error_code %d request_code %d minor_code %d\n", buf, error->serial, error->error_code, error->request_code, error->minor_code); } // Uncomment to forward to the default error handler #if 0 if (gs_pfnXErrorHandler) return gs_pfnXErrorHandler(display, error); #endif return 0; } #endif // __WXGTK__ bool MyApp::OnInit(void) { #if defined(__WXGTK__) // install the X error handler gs_pfnXErrorHandler = XSetErrorHandler( wxXErrorHandler ); #endif ... return true; }

Now the application will give a segmentation fault when an X11 error occurs, and if you have passed -sync to the application when running it, the crash should occur reasonably close to where the bad value was passed to an X11 function.

Simplify the Problem

If you have a bug that seems intractable, a good strategy is to try to reproduce the problem in the smallest possible application. You might take one of the wxWidgets samples and add code that demonstrates the problem. Or you could take a copy of the application source and strip it down to a bare minimum so that you can identify the code change that reveals or cures the bug. If you think the problem is in wxWidgets, then adding a small change to one of the samples will help you or the wxWidgets developers reproduce the problem and hopefully fix it.

Debugging a Release Build

Occasionally your application may work in debug mode but not in release mode, and this might be due to slight differences in the run-time library used by the compiler. If you are using Visual C++, you can create a new configuration that's identical to a debugging configuration but that defines NDEBUG, which means that all your application and wxWidgets debug symbols will be present, but the application will use the release version of the run-time library. This will enable you at least to eliminate the possibility of differences due to the run-time library version.

Normally you distribute your application in release mode with all debug information stripped, but if your customers are experiencing crashes that you find hard to reproduce, you might want to send them a debugging version of the application (on Windows, you might need to configure wxWidgets to link statically to the run-time library to avoid legal issues with the distribution of the debugging run-time DLL). You can compile your application with symbols that are used by an application called Dr. Watson that runs on your customer's PC and saves information about a crash. See your compiler information and the web for how to use the files that Dr. Watson writes to track down the cause of the crash.

If you are using MinGW, you can use a tool called Dr. MinGW that can catch exceptions such as segmentation faults and print a useful backtrace, if debugging is enabled in the code (-g has been specified). You can download it from http://www.mingw.org. If you have patient and cooperative customers, you can supply this tool for them to install on their computers and ask them to send you the reports.

On Unix, a debugging executable will produce a core file (depending on how the user has his or her system set up; see the documentation for the Unix command ulimit). You can place the core in the same file as your debugging executable, and the debugger will show where in your source files the crash occurred. However, core files can be very big, so your customer might not be very willing to send you the core dump.

Alternatively, your application can write log files that give status information at important parts of your application's execution. See also the documentation in the wxWidgets reference manual for the wxDebugReport class, which writes a report suitable for emailing to the application vendor. Similar functionality can be found in wxCrashPrint at http://wxcode.sf.net (for Linux) and BlackBox at http://www.codeproject.com/tools/blackbox.asp (for Windows).

    team bbl



    Cross-Platform GUI Programming with wxWidgets
    Cross-Platform GUI Programming with wxWidgets
    ISBN: 0131473816
    EAN: 2147483647
    Year: 2005
    Pages: 262

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net