Commit 89341602 by Benjamin Kosnik Committed by Benjamin Kosnik

debug_mode.html: Update.


2003-11-12  Benjamin Kosnik  <bkoz@redhat.com>

	* docs/html/debug_mode.html: Update.
	* docs/html/17_intro/TODO: Update.

From-SVN: r73525
parent f1045f1b
2003-11-12 Benjamin Kosnik <bkoz@redhat.com> 2003-11-12 Benjamin Kosnik <bkoz@redhat.com>
* docs/html/debug_mode.html: Update.
* docs/html/17_intro/TODO: Update.
2003-11-12 Benjamin Kosnik <bkoz@redhat.com>
* include/bits/c++config: Move using directive... * include/bits/c++config: Move using directive...
* include/debug/formatter.h: ...here. * include/debug/formatter.h: ...here.
......
...@@ -36,12 +36,18 @@ std::locale ...@@ -36,12 +36,18 @@ std::locale
functions and and LANG environment variable dependencies. functions and and LANG environment variable dependencies.
- use localedata to implement generic named (non-MT-safe) locales? - use localedata to implement generic named (non-MT-safe) locales?
Figure out a way to use ICU data, like libjava? Need a generic locale Figure out a way to use ICU data, like libjava? Re-package and use
model that does something besides the "C" locale. the glibc localedata, even if we aren't on linux? Need a generic
locale model that does something besides the "C" locale.
- make locale::classic() separate from named locale code. This will - make locale::classic() separate from named locale code. This will
improve the static linkage situation, but will require new improve the static linkage situation, but will require new
initialization code. initialization code. In particular, we need lazy-initialization of
locale::classic(), and maybe the has_facet/use_facet functions for all
the required facets. The end goal is a self-contained
locale_init.cc, or one with transitive closure without the locale
instantiations (locale-inst.cc) or the named locale bits
(localename.cc).
- Jerry(?)/Paolo(?) work on __float_to_char. - Jerry(?)/Paolo(?) work on __float_to_char.
...@@ -52,9 +58,9 @@ std::locale ...@@ -52,9 +58,9 @@ std::locale
std::basic_filebuf, 27_io std::basic_filebuf, 27_io
- wfilebuf, get variable-encoding working and tested, including - wfilebuf, get variable-encoding working and tested, including
positioning and seeking. positioning and seeking. (I think this may be done now)
- wfilebuf testsuite - wfilebuf testsuite (getting there...)
- look ahead for unbuffered io, so know when multiple putc's can be - look ahead for unbuffered io, so know when multiple putc's can be
coalesced. coalesced.
...@@ -90,9 +96,13 @@ testsuite ...@@ -90,9 +96,13 @@ testsuite
g++/binutils g++/binutils
- compression for wide versions of basic types - compression for wide versions of basic types, not just narrow
- get Apple's debug mode, or something with equivalent functionality, in. threads
- create MT abstraction layer for atomicity to pthreads.
- solution for threads + C++.
- audit for places where __builtin_expect can be used. - audit for places where __builtin_expect can be used.
...@@ -157,8 +167,6 @@ sources, with macro-guards. Also, same with the TR. ...@@ -157,8 +167,6 @@ sources, with macro-guards. Also, same with the TR.
- add feature-test macros for non-standard extensions - add feature-test macros for non-standard extensions
- create MT abstraction layer for atomicity to pthreads.
- add MT support for locale, string, istream, ostream - add MT support for locale, string, istream, ostream
- need to think about doing a .texi or DocBook manual, instead of all - need to think about doing a .texi or DocBook manual, instead of all
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta name="AUTHOR" content="dgregor@apple.com (Doug Gregor)" /> <meta name="AUTHOR" content="gregod@cs.rpi.edu (Doug Gregor)" />
<meta name="KEYWORDS" content="libstdc++, libstdc++-v3, GCC, g++, debug" /> <meta name="KEYWORDS" content="C++, GCC, libstdc++, g++, debug" />
<meta name="DESCRIPTION" content="Design of the libstdc++ debug mode." /> <meta name="DESCRIPTION" content="Design of the libstdc++ debug mode." />
<meta name="GENERATOR" content="vi and eight fingers" /> <meta name="GENERATOR" content="vi and eight fingers" />
<title>Design of the libstdc++ debug mode</title> <title>Design of the libstdc++ debug mode</title>
...@@ -249,7 +249,7 @@ ...@@ -249,7 +249,7 @@
following basic structure:</p> following basic structure:</p>
<pre> <pre>
template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt; template&lt;typename _Tp, typename _Allocator = allocator&lt;_Tp&gt;
class debug-list : class debug-list :
public release-list&lt;_Tp, _Allocator&gt;, public release-list&lt;_Tp, _Allocator&gt;,
public __gnu_debug::_Safe_sequence&lt;debug-list&lt;_Tp, _Allocator&gt; &gt; public __gnu_debug::_Safe_sequence&lt;debug-list&lt;_Tp, _Allocator&gt; &gt;
...@@ -309,12 +309,14 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt; ...@@ -309,12 +309,14 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt;
<p>Achieving link- and run-time coexistence is not a trivial <p>Achieving link- and run-time coexistence is not a trivial
implementation task. To achieve this goal we required a small implementation task. To achieve this goal we required a small
extension to the GNU C++ compiler (described in the section on extension to the GNU C++ compiler (described in the GCC Manual for
<a href="#mixing">link- and run-time coexistence</a>) and complex C++ Extensions, see <a href =
organization of debug- and release-modes. The end result is that we http://gcc.gnu.org/onlinedocs/gcc/Strong-Using.html>strong
have achieved per-use recompilation but have had to give up some using</a>), and a complex organization of debug- and
checking of the <code>std::basic_string</code> class template release-modes. The end result is that we have achieved per-use
(namely, safe iterators). recompilation but have had to give up some checking of the
<code>std::basic_string</code> class template (namely, safe
iterators).
<h4><a name="compile_coexistence">Compile-time coexistence of release- and <h4><a name="compile_coexistence">Compile-time coexistence of release- and
debug-mode components</a></h4> debug-mode components</a></h4>
...@@ -322,95 +324,129 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt; ...@@ -322,95 +324,129 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt;
components need to exist within a single translation unit so that components need to exist within a single translation unit so that
the debug versions can wrap the release versions. However, only one the debug versions can wrap the release versions. However, only one
of these components should be user-visible at any particular of these components should be user-visible at any particular
time with the standard name, e.g., <code>std::list</code>. In time with the standard name, e.g., <code>std::list</code>. </p>
release mode, we define only the release-mode version of the
<p>In release mode, we define only the release-mode version of the
component with its standard name and do not include the debugging component with its standard name and do not include the debugging
component at all (except, perhaps, in <code>__gnu_debug</code>, if component at all. The release mode version is defined within the
requested via the separate debugging headers). This method leaves the namespace <code>__gnu_nom</code>, and then associated with namespace
behavior of release mode completely unchanged from its behavior <code>std</code> via a "strong using" directive. Minus the
prior to the introduction of the libstdc++ debug mode.</p> namespace associations, this method leaves the behavior of release
mode completely unchanged from its behavior prior to the
<p>In debug mode we include the release-mode container into its introduction of the libstdc++ debug mode. Here's an example of what
natural namespace but perform renaming to an implementation-defined this ends up looking like, in C++.</p>
name using preprocessor macros. Thus the
release-mode <code>std::list</code> will be renamed <pre>
to <code>std::_Release_list</code> during debug mode, and we will namespace __gnu_norm
automatically include the debugging version with the {
name <code>std::list</code> for users to reference. This method using namespace std;
allows the debug- and release-mode versions of the same component to
coexist at compile-time without causing an unreasonable maintenance template&lt;typename _Tp, typename _Alloc = allocator&lt;_Tp&gt; &gt;
burden.</p> class list
{
// ...
};
} // namespace __gnu_norm
namespace std
{
using namespace __gnu_norm __attribute__ ((strong));
}
</pre>
<p>In debug mode we include the release-mode container and also the
debug-mode container. The release mode version is defined exactly as
before, and the debug-mode container is defined within the namespace
<code>__gnu_debug</code>, which is associated with namespace
<code>std</code> via a "strong using" directive. This method allows
the debug- and release-mode versions of the same component to coexist
at compile-time without causing an unreasonable maintenance burden,
while minimizing confusion. Again, this boils down to C++ code as
follows:</p>
<pre>
namespace __gnu_norm
{
using namespace std;
template&lt;typename _Tp, typename _Alloc = allocator&lt;_Tp&gt; &gt;
class list
{
// ...
};
} // namespace __gnu_norm
namespace __gnu_debug
{
using namespace std;
template&lt;typename _Tp, typename _Alloc = allocator&lt;_Tp&gt; &gt;
class list
: public __gnu_norm::list&lt;_Tp, _Alloc&gt;,
public __gnu_debug::_Safe_sequence&lt;list&lt;_Tp, _Alloc&gt; &gt;
{
// ...
};
} // namespace __gnu_norm
namespace std
{
using namespace __gnu_debug __attribute__ ((strong));
}
</pre>
<h4><a name="mixing">Link- and run-time coexistence of release- and <h4><a name="mixing">Link- and run-time coexistence of release- and
debug-mode components</a></h4> debug-mode components</a></h4>
<p>There is a problem with the simple compile-time coexistence
mechanism: if a user compiles some modules with release mode and
some modules with debug mode, the debuggable components will differ
in different translation units, violating the C++ One Definition
Rule (ODR). This violation will likely be detected at link time,
because the sizes of debug-mode containers will differ from the
sizes of release-mode containers, although in some cases (such as
dynamic linking) the error may be detected much later (or not at
all!).</p>
<p>Unfortunately, it is not possible to avoid violating the ODR with
most debug mode designs (see the section on <a
href="#coexistence_alt">alternatives for coexistence</a>), so the
philosophy of the libstdc++ debug mode is to acknowledge that there
is an unavoidable ODR violation in this case but to ensure that the
ODR violation does not affect execution. To accomplish this, the
libstdc++ debug mode uses the aforementioned preprocessor renaming
scheme but includes an additional renaming scheme that happens at
compile-time that essentially reverses the preprocessor
renaming <em>from the linker's point of view</em>. Thus, in debug
mode, the release-mode <code>list</code> container is
named <code>std::_Release_list</code> but will be mangled with the
name <code>std::list</code> (as it was in release mode). Similarly,
the debug-mode <code>list</code> is named <code>std::list</code>
(in debug mode) but will be mangled
as <code>std::_Debug_list</code>. Thus the
release-mode <code>list</code> always compiles down to code that
uses the name <code>std::list</code>, and the
debug-mode <code>list</code> always compiles down to code that uses
the name <code>std::_Debug_list</code>, independent of the use of
debug mode. This has several positive effects:</p>
<ul> <p>Because each component has a distinct and separate release and
<li>No linking conflicts between debug/release objects: because the debug implementation, there are are no issues with link-time
names of the debug- and release-mode containers are different in the coexistence: the separate namespaces result in different mangled
compiled object files, there are no link-time conflicts between the names, and thus unique linkage.</p>
two.</li>
<p>However, components that are defined and used within the C++
<li>Release-mode code is shared: the release-mode code can be shared standard library itself face additional constraints. For instance,
within a program, even with it is compiled partly in release-mode some of the member functions of <code> std::moneypunct</code> return
and partly in debug-mode, because the release-mode code is unchanged <code>std::basic_string</code>. Normally, this is not a problem, but
in name and function. This can decrease the size of mixed with a mixed mode standard library that could be using either
debug/release binaries.</li> debug-mode or release-mode <code> basic_string</code> objects, things
get more complicated. As the return value of a function is not
<li>Able to catch <em>most</em> invalid debug/release combinations: encoded into the mangled name, there is no way to specify a
because the names of debug- and release-mode containers are release-mode or a debug-mode string. In practice, this results in
different in the compiled object files, if a debug/release runtime errors. A simplified example of this problem is as follows.
interaction cannot occur (e.g., because a container a translation </p>
unit compiled in debug mode is passed to a routine in a translation
unit compiled in release mode) the result will be an undefined <p> Take this translation unit, compiled in debug-mode: <p>
symbol at link time. The undefined symbol occurs because the mangled <pre>
name of the definition will contain the release-mode container type // -D_GLIBCXX_DEBUG
and the mangled name of the reference will contain the debug-mode #include <string>
container type. However, we cannot detect these collisions if the
only use of the container is in the return type, because the return std::string test02();
type is not part of the mangled name of a function.</li>
</ul> std::string test01()
{
return test02();
}
int main()
{
test01();
return 0;
}
</pre>
<p>The new <code>link_name</code> class attribute facilities <p> ... and linked to this translation unit, compiled in release mode:</p>
renaming. It may be attached to any class type (or any class
template) to override the name of the class used for name
mangling. For instance, a class named <code>bar</code> would
generally mangle as <code>3bar</code>; if the class has
a <code>link_name</code> attribute that specifies the string
"wibble", then it would mangle as <code>6wibble</code>.</p>
<p>Note that although we have hidden the ODR violation, it still <pre>
exists. For this reason we cannot easily provide safe iterators for #include <string>
std::string
test02()
{
return std::string("toast");
}
</pre>
<p> For this reason we cannot easily provide safe iterators for
the <code>std::basic_string</code> class template, as it is present the <code>std::basic_string</code> class template, as it is present
throughout the C++ standard library. For instance, locale facets throughout the C++ standard library. For instance, locale facets
define typedefs that include <code>basic_string</code>: in a mixed define typedefs that include <code>basic_string</code>: in a mixed
...@@ -445,7 +481,7 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt; ...@@ -445,7 +481,7 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt;
release-compiled translation units is enormous.</p> release-compiled translation units is enormous.</p>
<h4><a name="coexistence_alt">Alternatives for Coexistence</a></h4> <h4><a name="coexistence_alt">Alternatives for Coexistence</a></h4>
<p>The coexistence scheme was chosen over many alternatives, <p>The coexistence scheme above was chosen over many alternatives,
including language-only solutions and solutions that also required including language-only solutions and solutions that also required
extensions to the C++ front end. The following is a partial list of extensions to the C++ front end. The following is a partial list of
solutions, with justifications for our rejection of each.</p> solutions, with justifications for our rejection of each.</p>
...@@ -491,19 +527,12 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt; ...@@ -491,19 +527,12 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt;
declarations disallow specialization. This method fails declarations disallow specialization. This method fails
the <b>correctness</b> criteria.</li> the <b>correctness</b> criteria.</li>
<li><em>Extension: allow template aliasing/renaming</em>: This is <li><em> Use implementation-specific properties of anonymous
the runner-up to the <code>link_name</code> solution, eliminated namespaces. </em>
only because it requires more extensive compiler changes See <a
than <code>link_name</code>. In this model, we would define the href="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00004.html"> this post
debug containers in a different namespace </a> </li>
(e.g., <code>__gnu_debug</code>) and then import them (e.g., with This method fails the <b>correctness</b> criteria.</li>
an extended <code>using</code> declaration that aliases templates,
such as that of <a
href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1449.pdf">template
aliases</a> proposal). This solution is workable, and in fact
would be desirable in the long run, but requires a sizeable change
to the C++ compiler front-end that is not within the scope of
this project.</li>
<li><em>Extension: allow reopening on namespaces</em>: This would <li><em>Extension: allow reopening on namespaces</em>: This would
allow the debug mode to effectively alias the allow the debug mode to effectively alias the
...@@ -518,6 +547,21 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt; ...@@ -518,6 +547,21 @@ template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt;
recompilation</b> requirement, because we would only be able to recompilation</b> requirement, because we would only be able to
support option (1) or (2).</li> support option (1) or (2).</li>
</li> </li>
<li><em>Extension: use link name</em>: This option involves
complicated re-naming between debug-mode and release-mode
components at compile time, and then a g++ extension called <em>
link name </em> to recover the original names at link time. There
are two drawbacks to this approach. One, it's very verbose,
relying on macro renaming at compile time and several levels of
include ordering. Two, ODR issues remained with container member
functions taking no arguments in mixed-mode settings resulting in
equivalent link names, <code> vector::push_back() </code> being
one example.
See <a
href="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00177.html">link
name</a> </li>
</li>
</ul> </ul>
<p>Other options may exist for implementing the debug mode, many of <p>Other options may exist for implementing the debug mode, many of
......
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