[PATCH] Update documentation regarding bogus memory leaks in libstdc++

Jonathan Wakely jwakely@redhat.com
Wed Apr 10 19:24:00 GMT 2019


	* doc/xml/faq.xml: Add information about emergency EH pool.
	* doc/xml/manual/debug.xml: Update list of memory debugging tools.
	Move outdated information on mt_allocator to a separate section.
	* doc/xml/manual/evolution.xml: Clarify that GLIBCXX_FORCE_NEW
	doesn't affect the default allocator.

I haven't regenerated the HTML docs, as further doc patches are coming
soon.

Committed to trunk.

-------------- next part --------------
commit 0d4f98089277ae49ea56471e74658cb367284f7f
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Apr 10 20:20:22 2019 +0100

    Update documentation regarding bogus memory leaks in libstdc++
    
            * doc/xml/faq.xml: Add information about emergency EH pool.
            * doc/xml/manual/debug.xml: Update list of memory debugging tools.
            Move outdated information on mt_allocator to a separate section.
            * doc/xml/manual/evolution.xml: Clarify that GLIBCXX_FORCE_NEW
            doesn't affect the default allocator.

diff --git a/libstdc++-v3/doc/xml/faq.xml b/libstdc++-v3/doc/xml/faq.xml
index edc07f16acb..b4bf333e26a 100644
--- a/libstdc++-v3/doc/xml/faq.xml
+++ b/libstdc++-v3/doc/xml/faq.xml
@@ -1001,21 +1001,31 @@
 <qandaentry xml:id="faq.memory_leaks">
   <question xml:id="q-memory_leaks">
     <para>
-      <quote>Memory leaks</quote> in containers
+      <quote>Memory leaks</quote> in libstdc++
     </para>
   </question>
   <answer xml:id="a-memory_leaks">
-    <note>
-      <para>This answer is old and probably no longer be relevant.</para>
-    </note>
     <para>
-    A few people have reported that the standard containers appear
+    Since GCC 5.1.0, libstdc++ automatically allocates a pool
+    of a few dozen kilobytes on startup. This pool is used to ensure it's
+    possible to throw exceptions (such as <classname>bad_alloc</classname>)
+    even when <code>malloc</code> is unable to allocate any more memory.
+    With some versions of <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://valgrind.org/"><command>valgrind</command></link>
+    this pool will be shown as "still reachable" when the process exits, e.g.
+    <code>still reachable: 72,704 bytes in 1 blocks</code>.
+    This memory is not a leak, because it's still in use by libstdc++,
+    and the memory will be returned to the OS when the process exits.
+    Later versions of <command>valgrind</command> know how to free this
+    pool as the process exits, and so won't show any "still reachable" memory.
+    </para>
+    <para>
+    In the past, a few people reported that the standard containers appear
     to leak memory when tested with memory checkers such as
     <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://valgrind.org/"><command>valgrind</command></link>.
     Under some (non-default) configurations the library's allocators keep
     free memory in a
-    pool for later reuse, rather than returning it to the OS.  Although
-    this memory is always reachable by the library and is never
+    pool for later reuse, rather than deallocating it with <code>delete</code>
+    Although this memory is always reachable by the library and is never
     lost, memory debugging tools can report it as a leak.  If you
     want to test the library for memory leaks please read
     <link linkend="debug.memory">Tips for memory leak hunting</link>
diff --git a/libstdc++-v3/doc/xml/manual/debug.xml b/libstdc++-v3/doc/xml/manual/debug.xml
index 37e330d3ed2..091e0b6914c 100644
--- a/libstdc++-v3/doc/xml/manual/debug.xml
+++ b/libstdc++-v3/doc/xml/manual/debug.xml
@@ -94,50 +94,35 @@
 
 <section xml:id="debug.memory"><info><title>Memory Leak Hunting</title></info>
 
+<para>
+  On many targets GCC supports AddressSanitizer, a fast memory error detector,
+  which is enabled by the <option>-fsanitize=address</option> option.
+</para>
 
 <para>
-  There are various third party memory tracing and debug utilities
+  There are also various third party memory tracing and debug utilities
   that can be used to provide detailed memory allocation information
   about C++ code. An exhaustive list of tools is not going to be
   attempted, 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 a
-  replacement for the global new and delete operators that can track
-  memory allocation and deallocation and provide useful memory
-  statistics.
-</para>
-
-<para>
-  Regardless of the memory debugging tool being used, there is one
-  thing of great importance to keep in mind when debugging C++ code
-  that uses <code>new</code> and <code>delete</code>: there are
-  different 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 and
-  look specifically for <code>GLIBCXX_FORCE_NEW</code>.
-</para>
-
-<para>
-  In a nutshell, the optional <classname>mt_allocator</classname>
-  is a high-performance pool allocator, and can
-  give the mistaken impression that in a suspect executable, memory is
-  being leaked, when in reality the memory "leak" is a pool being used
-  by the library's allocator and is reclaimed after program
-  termination.
+  <code>mudflap</code> (no longer supported since GCC 4.9.0), ElectricFence,
+  and the non-free commercial product <code>purify</code>.
+  In addition, <code>libcwd</code>, jemalloc and TCMalloc have replacements
+  for the global <code>new</code> and <code>delete</code> operators
+  that can track memory allocation and deallocation and provide useful
+  memory statistics.
 </para>
 
 <para>
   For valgrind, there are some specific items to keep in mind. First
   of all, use a version of valgrind that will work with current GNU
   C++ tools: the first that can do this is valgrind 1.0.4, but later
-  versions should work at least as well. Second of all, use a
-  completely unoptimized build to avoid confusing valgrind. Third, use
-  GLIBCXX_FORCE_NEW to keep extraneous pool allocation noise from
-  cluttering debug information.
+  versions should work better. Second, using an unoptimized build
+  might avoid confusing valgrind.
 </para>
 
 <para>
-  Fourth, it may be necessary to force deallocation in other libraries
-  as well, namely the "C" library. On linux, this can be accomplished
+  Third, it may be necessary to force deallocation in other libraries
+  as well, namely the "C" library. On GNU/Linux, this can be accomplished
   with the appropriate use of the <code>__cxa_atexit</code> or
   <code>atexit</code> functions.
 </para>
@@ -157,7 +142,6 @@
    }
 </programlisting>
 
-
 <para>or, using <code>__cxa_atexit</code>:</para>
 
 <programlisting>
@@ -184,6 +168,39 @@
    valgrind -v --num-callers=20 --leak-check=yes --leak-resolution=high --show-reachable=yes a.out
 </programlisting>
 
+<section xml:id="debug.memory.mtalloc">
+<info><title>Non-memory leaks in Pool and MT allocators</title></info>
+
+<para>
+  There are different kinds of allocation schemes that can be used by
+  <code>std::allocator</code>. Prior to GCC 3.4.0 the default was to use
+  a pooling allocator, <classname>pool_allocator</classname>,
+  which is still available as the optional
+  <classname>__pool_alloc</classname> extension.
+  Another optional extension, <classname>__mt_alloc</classname>,
+  is a high-performance pool allocator.
+</para>
+
+<para>
+  In a suspect executable these pooling allocators can give
+  the mistaken impression that memory is being leaked,
+  when in reality the memory "leak" is a pool being used
+  by the library's allocator and is reclaimed after program
+  termination.
+</para>
+
+<para>
+  If you're using memory debugging tools on a program that uses
+  one of these pooling allocators, you can set the environment variable
+  <literal>GLIBCXX_FORCE_NEW</literal> to keep extraneous pool allocation
+  noise from cluttering debug information.
+  For more details, see the
+  <link linkend="manual.ext.allocator.mt">mt allocator</link>
+  documentation and look specifically for <code>GLIBCXX_FORCE_NEW</code>.
+</para>
+
+</section>
+
 </section>
 
 <section xml:id="debug.races"><info><title>Data Race Hunting</title></info>
diff --git a/libstdc++-v3/doc/xml/manual/evolution.xml b/libstdc++-v3/doc/xml/manual/evolution.xml
index e24418fefc0..c7efb8f0f8a 100644
--- a/libstdc++-v3/doc/xml/manual/evolution.xml
+++ b/libstdc++-v3/doc/xml/manual/evolution.xml
@@ -79,11 +79,12 @@ Removal of <filename class="headerfile"><ext/tree></filename>, moved to <f
 
    <para> For GCC releases from 2.95 through the 3.1 series, defining
    <literal>__USE_MALLOC</literal> on the gcc command line would change the
-   default allocation strategy to instead use <code> malloc</code> and
-   <function>free</function>. For the 3.2 and 3.3 release series the same
+   default allocation strategy to instead use <code>malloc</code> and
+   <code>free</code>. For the 3.2 and 3.3 release series the same
    functionality was spelled <literal>_GLIBCXX_FORCE_NEW</literal>. From
-   GCC 3.4 onwards the functionality is enabled by setting
-   <literal>GLIBCXX_FORCE_NEW</literal> in the environment, see
+   GCC 3.4 onwards the default allocator uses <code>new</code> anyway,
+   but for the optional pooling allocators the functionality is enabled by
+   setting <literal>GLIBCXX_FORCE_NEW</literal> in the environment, see
    <link linkend="manual.ext.allocator.mt">the mt allocator chapter</link>
    for details.
    </para>


More information about the Libstdc++ mailing list