<section xmlns="http://docbook.org/ns/docbook" version="5.0"xml:id="manual.intro.using.debug" xreflabel="Debugging Support"><?dbhtml filename="debug.html"?><info><title>Debugging Support</title><keywordset><keyword>C++</keyword><keyword>debug</keyword></keywordset></info><para>There are numerous things that can be done to improve the ease withwhich C++ binaries are debugged when using the GNU tool chain. Hereare some of them.</para><section xml:id="debug.compiler"><info><title>Using <command>g++</command></title></info><para>Compiler flags determine how debug information is transmittedbetween compilation and debug or analysis tools.</para><para>The default optimizations and debug flags for a libstdc++ buildare <code>-g -O2</code>. However, both debug and optimizationflags can be varied to change debugging characteristics. Forinstance, turning off all optimization via the <code>-g -O0-fno-inline</code> flags will disable inlining and optimizations,and add debugging information, so that stepping through all functions,(including inlined constructors and destructors) is possible. Inaddition, <code>-fno-eliminate-unused-debug-types</code> can beused when additional debug information, such as nested class info,is desired.</para><para>Or, the debug format that the compiler and debugger use tocommunicate information about source constructs can be changed via<code>-gdwarf-2</code> or <code>-gstabs</code> flags: some debuggingformats permit more expressive type and scope information to beshown in GDB. Expressiveness can be enhanced by flags like<code>-g3</code>. The default debug information for a particularplatform can be identified via the value set by thePREFERRED_DEBUGGING_TYPE macro in the gcc sources.</para><para>Many other options are available: please see <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging%20Options">"Optionsfor Debugging Your Program"</link> in Using the GNU CompilerCollection (GCC) for a complete list.</para></section><section xml:id="debug.req"><info><title>Debug Versions of Library Binary Files</title></info><para>If you would like debug symbols in libstdc++, there are two ways tobuild libstdc++ with debug flags. The first is to run make from thetoplevel in a freshly-configured tree with</para><programlisting>--enable-libstdcxx-debug</programlisting><para>and perhaps</para><programlisting>--enable-libstdcxx-debug-flags='...'</programlisting><para>to create a separate debug build. Both the normal build and thedebug build will persist, without having to specify<code>CXXFLAGS</code>, and the debug library will be installed in aseparate directory tree, in <code>(prefix)/lib/debug</code>. Formore information, look at the <link linkend="manual.intro.setup.configure">configuration</link> section.</para><para>A second approach is to use the configuration flags</para><programlisting>make CXXFLAGS='-g3 -fno-inline -O0' all</programlisting><para>This quick and dirty approach is often sufficient for quickdebugging tasks, when you cannot or don't want to recompile yourapplication to use the <link linkend="manual.ext.debug_mode">debug mode</link>.</para></section><section xml:id="debug.memory"><info><title>Memory Leak Hunting</title></info><para>There are various third party memory tracing and debug utilitiesthat can be used to provide detailed memory allocation informationabout C++ code. An exhaustive list of tools is not going to beattempted, but includes <code>mtrace</code>, <code>valgrind</code>,<code>mudflap</code>, and the non-free commercial product<code>purify</code>. In addition, <code>libcwd</code> has areplacement for the global new and delete operators that can trackmemory allocation and deallocation and provide useful memorystatistics.</para><para>Regardless of the memory debugging tool being used, there is onething of great importance to keep in mind when debugging C++ codethat uses <code>new</code> and <code>delete</code>: there aredifferent kinds of allocation schemes that can be used by <code>std::allocator </code>. For implementation details, see the <link linkend="manual.ext.allocator.mt">mt allocator</link> documentation andlook specifically for <code>GLIBCXX_FORCE_NEW</code>.</para><para>In a nutshell, the default allocator used by <code>std::allocator</code> is a high-performance pool allocator, and cangive the mistaken impression that in a suspect executable, memory isbeing leaked, when in reality the memory "leak" is a pool being usedby the library's allocator and is reclaimed after programtermination.</para><para>For valgrind, there are some specific items to keep in mind. Firstof all, use a version of valgrind that will work with current GNUC++ tools: the first that can do this is valgrind 1.0.4, but laterversions should work at least as well. Second of all, use acompletely unoptimized build to avoid confusing valgrind. Third, useGLIBCXX_FORCE_NEW to keep extraneous pool allocation noise fromcluttering debug information.</para><para>Fourth, it may be necessary to force deallocation in other librariesas well, namely the "C" library. On linux, this can be accomplishedwith the appropriate use of the <code>__cxa_atexit</code> or<code>atexit</code> functions.</para><programlisting>#include <cstdlib>extern "C" void __libc_freeres(void);void do_something() { }int main(){atexit(__libc_freeres);do_something();return 0;}</programlisting><para>or, using <code>__cxa_atexit</code>:</para><programlisting>extern "C" void __libc_freeres(void);extern "C" int __cxa_atexit(void (*func) (void *), void *arg, void *d);void do_something() { }int main(){extern void* __dso_handle __attribute__ ((__weak__));__cxa_atexit((void (*) (void *)) __libc_freeres, NULL,&__dso_handle ? __dso_handle : NULL);do_test();return 0;}</programlisting><para>Suggested valgrind flags, given the suggestions above about settingup the runtime environment, library, and test file, might be:</para><programlisting>valgrind -v --num-callers=20 --leak-check=yes --leak-resolution=high --show-reachable=yes a.out</programlisting></section><section xml:id="debug.races"><info><title>Data Race Hunting</title></info><para>All synchronization primitives used in the library internals need to beunderstood by race detectors so that they do not produce false reports.</para><para>Two annotation macros are used to explain low-level synchronizationto race detectors:<code>_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE()</code> and<code> _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER()</code>.By default, these macros are defined empty -- anyone who wantsto use a race detector needs to redefine them to call anappropriate API.Since these macros are empty by default when the library is built,redefining them will only affect inline functions and templateinstantiations which are compiled in user code. This allows annotationof templates such as <code>shared_ptr</code>, but not code which isonly instantiated in the library.In order to annotate <code>basic_string</code> reference counting itis necessary to disable extern templates (by defining<code>_GLIBCXX_EXTERN_TEMPLATE=-1</code>) or to rebuild the<code>.so</code> file.Annotating the remaining atomic operations (at the time of writing theseare in <code>ios_base::Init::~Init</code>, <code>locale::_Impl</code> and<code>locale::facet</code>) requires rebuilding the <code>.so</code> file.</para><para>The approach described above is known to work with the following racedetection tools:<link xmlns:xlink="http://www.w3.org/1999/xlink"xlink:href="http://valgrind.org/docs/manual/drd-manual.html">DRD</link>,<link xmlns:xlink="http://www.w3.org/1999/xlink"xlink:href="http://valgrind.org/docs/manual/hg-manual.html">Helgrind</link>, and<link xmlns:xlink="http://www.w3.org/1999/xlink"xlink:href="http://code.google.com/p/data-race-test">ThreadSanitizer</link>.</para><para>With DRD, Helgrind and ThreadSanitizer you will need to definethe macros like this:<programlisting>#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) ANNOTATE_HAPPENS_BEFORE(A)#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) ANNOTATE_HAPPENS_AFTER(A)</programlisting>Refer to the documentation of each particular tool for details.</para></section><section xml:id="debug.gdb"><info><title>Using <command>gdb</command></title></info><para></para><para>Many options are available for GDB itself: please see <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://sources.redhat.com/gdb/current/onlinedocs/gdb/">"GDB features for C++" </link> in the GDB documentation. Alsorecommended: the other parts of this manual.</para><para>These settings can either be switched on in at the GDB command line,or put into a .gdbint file to establish default debuggingcharacteristics, like so:</para><programlisting>set print pretty onset print object onset print static-members onset print vtbl onset print demangle onset demangle-style gnu-v3</programlisting><para>Starting with version 7.0, GDB includes support for writingpretty-printers in Python. Pretty printers for STL classes aredistributed with GCC from version 4.5.0. The most recent version ofthese printers are always found in libstdc++ svn repository.To enable these printers, check-out the latest printers to a localdirectory:</para><programlisting>svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python</programlisting><para>Next, add the following section to your ~/.gdbinit The path mustmatch the location where the Python module above was checked-out.So if checked out to: /home/maude/gdb_printers/, the path would be aswritten in the example below.</para><programlisting>pythonimport syssys.path.insert(0, '/home/maude/gdb_printers/python')from libstdcxx.v6.printers import register_libstdcxx_printersregister_libstdcxx_printers (None)end</programlisting><para>The path should be the only element that needs to be adjusted in theexample. Once loaded, STL classes that the printers supportshould print in a more human-readable format. To print the classesin the old style, use the /r (raw) switch in the print command(i.e., print /r foo). This will print the classes as if the Pythonpretty-printers were not loaded.</para><para>For additional information on STL support and GDB please visit:<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://sourceware.org/gdb/wiki/STLSupport"> "GDB Supportfor STL" </link> in the GDB wiki. Additionally, in-depthdocumentation and discussion of the pretty printing feature can befound in "Pretty Printing" node in the GDB manual. You can findon-line versions of the GDB user manual in GDB's homepage, at<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://sourceware.org/gdb/"> "GDB: The GNU ProjectDebugger" </link>.</para></section><section xml:id="debug.exceptions"><info><title>Tracking uncaught exceptions</title></info><para>The <link linkend="support.termination.verbose">verbosetermination handler</link> gives information about uncaughtexceptions which are killing the program. It is described in thelinked-to page.</para></section><section xml:id="debug.debug_mode"><info><title>Debug Mode</title></info><para> The <link linkend="manual.ext.debug_mode">Debug Mode</link>has compile and run-time checks for many containers.</para></section><section xml:id="debug.compile_time_checks"><info><title>Compile Time Checking</title></info><para> The <link linkend="manual.ext.compile_checks">Compile-TimeChecks</link> Extension has compile-time checks for many algorithms.</para></section><section xml:id="debug.profile_mode" xreflabel="debug.profile_mode"><info><title>Profile-based Performance Analysis</title></info><para> The <link linkend="manual.ext.profile_mode">Profile-basedPerformance Analysis</link> Extension has performance checks for manyalgorithms.</para></section></section>