Commit 51d3c11a by Jonathan Wakely Committed by Jonathan Wakely

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.

From-SVN: r270264
parent a7f8aa3e
2019-04-10 Jonathan Wakely <jwakely@redhat.com> 2019-04-10 Jonathan Wakely <jwakely@redhat.com>
* 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.
* testsuite/lib/libstdc++.exp (check_v3_target_parallel_mode): Fix * testsuite/lib/libstdc++.exp (check_v3_target_parallel_mode): Fix
typo. typo.
......
...@@ -1001,21 +1001,31 @@ ...@@ -1001,21 +1001,31 @@
<qandaentry xml:id="faq.memory_leaks"> <qandaentry xml:id="faq.memory_leaks">
<question xml:id="q-memory_leaks"> <question xml:id="q-memory_leaks">
<para> <para>
<quote>Memory leaks</quote> in containers <quote>Memory leaks</quote> in libstdc++
</para> </para>
</question> </question>
<answer xml:id="a-memory_leaks"> <answer xml:id="a-memory_leaks">
<note>
<para>This answer is old and probably no longer be relevant.</para>
</note>
<para> <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 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>. <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 Under some (non-default) configurations the library's allocators keep
free memory in a free memory in a
pool for later reuse, rather than returning it to the OS. Although pool for later reuse, rather than deallocating it with <code>delete</code>
this memory is always reachable by the library and is never Although this memory is always reachable by the library and is never
lost, memory debugging tools can report it as a leak. If you lost, memory debugging tools can report it as a leak. If you
want to test the library for memory leaks please read want to test the library for memory leaks please read
<link linkend="debug.memory">Tips for memory leak hunting</link> <link linkend="debug.memory">Tips for memory leak hunting</link>
......
...@@ -94,50 +94,35 @@ ...@@ -94,50 +94,35 @@
<section xml:id="debug.memory"><info><title>Memory Leak Hunting</title></info> <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> <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 that can be used to provide detailed memory allocation information
about C++ code. An exhaustive list of tools is not going to be about C++ code. An exhaustive list of tools is not going to be
attempted, but includes <code>mtrace</code>, <code>valgrind</code>, attempted, but includes <code>mtrace</code>, <code>valgrind</code>,
<code>mudflap</code>, and the non-free commercial product <code>mudflap</code> (no longer supported since GCC 4.9.0), ElectricFence,
<code>purify</code>. In addition, <code>libcwd</code> has a and the non-free commercial product <code>purify</code>.
replacement for the global new and delete operators that can track In addition, <code>libcwd</code>, jemalloc and TCMalloc have replacements
memory allocation and deallocation and provide useful memory for the global <code>new</code> and <code>delete</code> operators
statistics. that can track memory allocation and deallocation and provide useful
</para> memory statistics.
<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.
</para> </para>
<para> <para>
For valgrind, there are some specific items to keep in mind. First 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 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 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 versions should work better. Second, using an unoptimized build
completely unoptimized build to avoid confusing valgrind. Third, use might avoid confusing valgrind.
GLIBCXX_FORCE_NEW to keep extraneous pool allocation noise from
cluttering debug information.
</para> </para>
<para> <para>
Fourth, it may be necessary to force deallocation in other libraries Third, it may be necessary to force deallocation in other libraries
as well, namely the "C" library. On linux, this can be accomplished as well, namely the "C" library. On GNU/Linux, this can be accomplished
with the appropriate use of the <code>__cxa_atexit</code> or with the appropriate use of the <code>__cxa_atexit</code> or
<code>atexit</code> functions. <code>atexit</code> functions.
</para> </para>
...@@ -157,7 +142,6 @@ ...@@ -157,7 +142,6 @@
} }
</programlisting> </programlisting>
<para>or, using <code>__cxa_atexit</code>:</para> <para>or, using <code>__cxa_atexit</code>:</para>
<programlisting> <programlisting>
...@@ -184,6 +168,39 @@ ...@@ -184,6 +168,39 @@
valgrind -v --num-callers=20 --leak-check=yes --leak-resolution=high --show-reachable=yes a.out valgrind -v --num-callers=20 --leak-check=yes --leak-resolution=high --show-reachable=yes a.out
</programlisting> </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>
<section xml:id="debug.races"><info><title>Data Race Hunting</title></info> <section xml:id="debug.races"><info><title>Data Race Hunting</title></info>
......
...@@ -79,11 +79,12 @@ Removal of <filename class="headerfile">&lt;ext/tree&gt;</filename>, moved to <f ...@@ -79,11 +79,12 @@ Removal of <filename class="headerfile">&lt;ext/tree&gt;</filename>, moved to <f
<para> For GCC releases from 2.95 through the 3.1 series, defining <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 <literal>__USE_MALLOC</literal> on the gcc command line would change the
default allocation strategy to instead use <code> malloc</code> and default allocation strategy to instead use <code>malloc</code> and
<function>free</function>. For the 3.2 and 3.3 release series the same <code>free</code>. For the 3.2 and 3.3 release series the same
functionality was spelled <literal>_GLIBCXX_FORCE_NEW</literal>. From functionality was spelled <literal>_GLIBCXX_FORCE_NEW</literal>. From
GCC 3.4 onwards the functionality is enabled by setting GCC 3.4 onwards the default allocator uses <code>new</code> anyway,
<literal>GLIBCXX_FORCE_NEW</literal> in the environment, see 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> <link linkend="manual.ext.allocator.mt">the mt allocator chapter</link>
for details. for details.
</para> </para>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment