OLD | NEW |
| (Empty) |
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or
g/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
3 <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" /><title>Design</title><meta name="generator
" content="DocBook XSL Stylesheets V1.74.0" /><meta name="keywords" content="
0; C++ , library , debug " />
<meta name="keywords" content=" ISO C++ , library&#
10; " /><link rel="home" href="../spine.html" title="The GNU C++ Library Docu
mentation" /><link rel="up" href="debug_mode.html" title="Chapter 30. Debug Mode
" /><link rel="prev" href="bk01pt12ch30s03.html" title="Using" /><link rel="next
" href="parallel_mode.html" title="Chapter 31. Parallel Mode" /></head><body><di
v class="navheader"><table width="100%" summary="Navigation header"><tr><th cols
pan="3" align="center">Design</th></tr><tr><td width="20%" align="left"><a acces
skey="p" href="bk01pt12ch30s03.html">Prev</a> </td><th width="60%" align="center
">Chapter 30. Debug Mode</th><td width="20%" align="right"> <a accesskey="n" hre
f="parallel_mode.html">Next</a></td></tr></table><hr /></div><div class="sect1"
lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style
="clear: both"><a id="manual.ext.debug_mode.design"></a>Design</h2></div></div><
/div><p> | |
4 </p><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><di
v><h3 class="title"><a id="manual.ext.debug_mode.design.goals"></a>Goals</h3></d
iv></div></div><p> | |
5 </p><p> The libstdc++ debug mode replaces unsafe (but efficient) standard | |
6 containers and iterators with semantically equivalent safe standard | |
7 containers and iterators to aid in debugging user programs. The | |
8 following goals directed the design of the libstdc++ debug mode:</p><div class
="itemizedlist"><ul type="disc"><li><p><span class="emphasis"><em>Correctness</e
m></span>: the libstdc++ debug mode must not change | |
9 the semantics of the standard library for all cases specified in | |
10 the ANSI/ISO C++ standard. The essence of this constraint is that | |
11 any valid C++ program should behave in the same manner regardless | |
12 of whether it is compiled with debug mode or release mode. In | |
13 particular, entities that are defined in namespace std in release | |
14 mode should remain defined in namespace std in debug mode, so that | |
15 legal specializations of namespace std entities will remain | |
16 valid. A program that is not valid C++ (e.g., invokes undefined | |
17 behavior) is not required to behave similarly, although the debug | |
18 mode will abort with a diagnostic when it detects undefined | |
19 behavior.</p></li><li><p><span class="emphasis"><em>Performance</em></span>:
the additional of the libstdc++ debug mode | |
20 must not affect the performance of the library when it is compiled | |
21 in release mode. Performance of the libstdc++ debug mode is | |
22 secondary (and, in fact, will be worse than the release | |
23 mode).</p></li><li><p><span class="emphasis"><em>Usability</em></span>: the
libstdc++ debug mode should be easy to | |
24 use. It should be easily incorporated into the user's development | |
25 environment (e.g., by requiring only a single new compiler switch) | |
26 and should produce reasonable diagnostics when it detects a | |
27 problem with the user program. Usability also involves detection | |
28 of errors when using the debug mode incorrectly, e.g., by linking | |
29 a release-compiled object against a debug-compiled object if in | |
30 fact the resulting program will not run correctly.</p></li><li><p><span clas
s="emphasis"><em>Minimize recompilation</em></span>: While it is expected that | |
31 users recompile at least part of their program to use debug | |
32 mode, the amount of recompilation affects the | |
33 detect-compile-debug turnaround time. This indirectly affects the | |
34 usefulness of the debug mode, because debugging some applications | |
35 may require rebuilding a large amount of code, which may not be | |
36 feasible when the suspect code may be very localized. There are | |
37 several levels of conformance to this requirement, each with its | |
38 own usability and implementation characteristics. In general, the | |
39 higher-numbered conformance levels are more usable (i.e., require | |
40 less recompilation) but are more complicated to implement than | |
41 the lower-numbered conformance levels. | |
42 </p><div class="orderedlist"><ol type="1"><li><p><span class="emphasis"><e
m>Full recompilation</em></span>: The user must recompile his or | |
43 her entire application and all C++ libraries it depends on, | |
44 including the C++ standard library that ships with the | |
45 compiler. This must be done even if only a small part of the | |
46 program can use debugging features.</p></li><li><p><span class="emphasis
"><em>Full user recompilation</em></span>: The user must recompile | |
47 his or her entire application and all C++ libraries it depends | |
48 on, but not the C++ standard library itself. This must be done | |
49 even if only a small part of the program can use debugging | |
50 features. This can be achieved given a full recompilation | |
51 system by compiling two versions of the standard library when | |
52 the compiler is installed and linking against the appropriate | |
53 one, e.g., a multilibs approach.</p></li><li><p><span class="emphasis"><
em>Partial recompilation</em></span>: The user must recompile the | |
54 parts of his or her application and the C++ libraries it | |
55 depends on that will use the debugging facilities | |
56 directly. This means that any code that uses the debuggable | |
57 standard containers would need to be recompiled, but code | |
58 that does not use them (but may, for instance, use IOStreams) | |
59 would not have to be recompiled.</p></li><li><p><span class="emphasis"><
em>Per-use recompilation</em></span>: The user must recompile the | |
60 parts of his or her application and the C++ libraries it | |
61 depends on where debugging should occur, and any other code | |
62 that interacts with those containers. This means that a set of | |
63 translation units that accesses a particular standard | |
64 container instance may either be compiled in release mode (no | |
65 checking) or debug mode (full checking), but must all be | |
66 compiled in the same way; a translation unit that does not see | |
67 that standard container instance need not be recompiled. This | |
68 also means that a translation unit <span class="emphasis"><em>A</em></sp
an> that contains a | |
69 particular instantiation | |
70 (say, <code class="code">std::vector<int></code>) compiled in rele
ase | |
71 mode can be linked against a translation unit <span class="emphasis"><em
>B</em></span> that | |
72 contains the same instantiation compiled in debug mode (a | |
73 feature not present with partial recompilation). While this | |
74 behavior is technically a violation of the One Definition | |
75 Rule, this ability tends to be very important in | |
76 practice. The libstdc++ debug mode supports this level of | |
77 recompilation. </p></li><li><p><span class="emphasis"><em>Per-unit recom
pilation</em></span>: The user must only | |
78 recompile the translation units where checking should occur, | |
79 regardless of where debuggable standard containers are | |
80 used. This has also been dubbed "<code class="code">-g</code> mode", | |
81 because the <code class="code">-g</code> compiler switch works in this w
ay, | |
82 emitting debugging information at a per--translation-unit | |
83 granularity. We believe that this level of recompilation is in | |
84 fact not possible if we intend to supply safe iterators, leave | |
85 the program semantics unchanged, and not regress in | |
86 performance under release mode because we cannot associate | |
87 extra information with an iterator (to form a safe iterator) | |
88 without either reserving that space in release mode | |
89 (performance regression) or allocating extra memory associated | |
90 with each iterator with <code class="code">new</code> (changes the progr
am | |
91 semantics).</p></li></ol></div><p> | |
92 </p></li></ul></div></div><div class="sect2" lang="en" xml:lang="en"><div cl
ass="titlepage"><div><div><h3 class="title"><a id="manual.ext.debug_mode.design.
methods"></a>Methods</h3></div></div></div><p> | |
93 </p><p>This section provides an overall view of the design of the | |
94 libstdc++ debug mode and details the relationship between design | |
95 decisions and the stated design goals.</p><div class="sect3" lang="en" xml:lan
g="en"><div class="titlepage"><div><div><h4 class="title"><a id="debug_mode.desi
gn.methods.wrappers"></a>The Wrapper Model</h4></div></div></div><p>The libstdc+
+ debug mode uses a wrapper model where the debugging | |
96 versions of library components (e.g., iterators and containers) form | |
97 a layer on top of the release versions of the library | |
98 components. The debugging components first verify that the operation | |
99 is correct (aborting with a diagnostic if an error is found) and | |
100 will then forward to the underlying release-mode container that will | |
101 perform the actual work. This design decision ensures that we cannot | |
102 regress release-mode performance (because the release-mode | |
103 containers are left untouched) and partially enables <a class="ulink" href="#m
ixing" target="_top">mixing debug and release code</a> at link time, | |
104 although that will not be discussed at this time.</p><p>Two types of wrappers
are used in the implementation of the debug | |
105 mode: container wrappers and iterator wrappers. The two types of | |
106 wrappers interact to maintain relationships between iterators and | |
107 their associated containers, which are necessary to detect certain | |
108 types of standard library usage errors such as dereferencing | |
109 past-the-end iterators or inserting into a container using an | |
110 iterator from a different container.</p><div class="sect4" lang="en" xml:lang=
"en"><div class="titlepage"><div><div><h5 class="title"><a id="debug_mode.design
.methods.safe_iter"></a>Safe Iterators</h5></div></div></div><p>Iterator wrapper
s provide a debugging layer over any iterator that | |
111 is attached to a particular container, and will manage the | |
112 information detailing the iterator's state (singular, | |
113 dereferenceable, etc.) and tracking the container to which the | |
114 iterator is attached. Because iterators have a well-defined, common | |
115 interface the iterator wrapper is implemented with the iterator | |
116 adaptor class template <code class="code">__gnu_debug::_Safe_iterator</code>, | |
117 which takes two template parameters:</p><div class="itemizedlist"><ul type="di
sc"><li><p><code class="code">Iterator</code>: The underlying iterator type, whi
ch must | |
118 be either the <code class="code">iterator</code> or <code class="code">const
_iterator</code> | |
119 typedef from the sequence type this iterator can reference.</p></li><li><p><
code class="code">Sequence</code>: The type of sequence that this iterator | |
120 references. This sequence must be a safe sequence (discussed below) | |
121 whose <code class="code">iterator</code> or <code class="code">const_iterator<
/code> typedef | |
122 is the type of the safe iterator.</p></li></ul></div></div><div class="sect4"
lang="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id
="debug_mode.design.methods.safe_seq"></a>Safe Sequences (Containers)</h5></div>
</div></div><p>Container wrappers provide a debugging layer over a particular | |
123 container type. Because containers vary greatly in the member | |
124 functions they support and the semantics of those member functions | |
125 (especially in the area of iterator invalidation), container | |
126 wrappers are tailored to the container they reference, e.g., the | |
127 debugging version of <code class="code">std::list</code> duplicates the entire | |
128 interface of <code class="code">std::list</code>, adding additional semantic | |
129 checks and then forwarding operations to the | |
130 real <code class="code">std::list</code> (a public base class of the debugging | |
131 version) as appropriate. However, all safe containers inherit from | |
132 the class template <code class="code">__gnu_debug::_Safe_sequence</code>, | |
133 instantiated with the type of the safe container itself (an instance | |
134 of the curiously recurring template pattern).</p><p>The iterators of a contain
er wrapper will be | |
135 <a class="ulink" href="#safe_iterator" target="_top">safe iterators</a> that r
eference sequences | |
136 of this type and wrap the iterators provided by the release-mode | |
137 base class. The debugging container will use only the safe | |
138 iterators within its own interface (therefore requiring the user to | |
139 use safe iterators, although this does not change correct user | |
140 code) and will communicate with the release-mode base class with | |
141 only the underlying, unsafe, release-mode iterators that the base | |
142 class exports.</p><p> The debugging version of <code class="code">std::list</c
ode> will have the | |
143 following basic structure:</p><pre class="programlisting"> | |
144 template<typename _Tp, typename _Allocator = allocator<_Tp> | |
145 class debug-list : | |
146 public release-list<_Tp, _Allocator>, | |
147 public __gnu_debug::_Safe_sequence<debug-list<_Tp, _Allocator> > | |
148 { | |
149 typedef release-list<_Tp, _Allocator> _Base; | |
150 typedef debug-list<_Tp, _Allocator> _Self; | |
151 | |
152 public: | |
153 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, _Self>
iterator; | |
154 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, _Self
> const_iterator; | |
155 | |
156 // duplicate std::list interface with debugging semantics | |
157 }; | |
158 </pre></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepa
ge"><div><div><h4 class="title"><a id="debug_mode.design.methods.precond"></a>Pr
econdition Checking</h4></div></div></div><p>The debug mode operates primarily b
y checking the preconditions of | |
159 all standard library operations that it supports. Preconditions that | |
160 are always checked (regardless of whether or not we are in debug | |
161 mode) are checked via the <code class="code">__check_xxx</code> macros defined | |
162 and documented in the source | |
163 file <code class="code">include/debug/debug.h</code>. Preconditions that may o
r | |
164 may not be checked, depending on the debug-mode | |
165 macro <code class="code">_GLIBCXX_DEBUG</code>, are checked via | |
166 the <code class="code">__requires_xxx</code> macros defined and documented in
the | |
167 same source file. Preconditions are validated using any additional | |
168 information available at run-time, e.g., the containers that are | |
169 associated with a particular iterator, the position of the iterator | |
170 within those containers, the distance between two iterators that may | |
171 form a valid range, etc. In the absence of suitable information, | |
172 e.g., an input iterator that is not a safe iterator, these | |
173 precondition checks will silently succeed.</p><p>The majority of precondition
checks use the aforementioned macros, | |
174 which have the secondary benefit of having prewritten debug | |
175 messages that use information about the current status of the | |
176 objects involved (e.g., whether an iterator is singular or what | |
177 sequence it is attached to) along with some static information | |
178 (e.g., the names of the function parameters corresponding to the | |
179 objects involved). When not using these macros, the debug mode uses | |
180 either the debug-mode assertion | |
181 macro <code class="code">_GLIBCXX_DEBUG_ASSERT</code> , its pedantic | |
182 cousin <code class="code">_GLIBCXX_DEBUG_PEDASSERT</code>, or the assertion | |
183 check macro that supports more advance formulation of error | |
184 messages, <code class="code">_GLIBCXX_DEBUG_VERIFY</code>. These macros are | |
185 documented more thoroughly in the debug mode source code.</p></div><div class=
"sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="titl
e"><a id="debug_mode.design.methods.coexistence"></a>Release- and debug-mode coe
xistence</h4></div></div></div><p>The libstdc++ debug mode is the first debug mo
de we know of that | |
186 is able to provide the "Per-use recompilation" (4) guarantee, that | |
187 allows release-compiled and debug-compiled code to be linked and | |
188 executed together without causing unpredictable behavior. This | |
189 guarantee minimizes the recompilation that users are required to | |
190 perform, shortening the detect-compile-debug bug hunting cycle | |
191 and making the debug mode easier to incorporate into development | |
192 environments by minimizing dependencies.</p><p>Achieving link- and run-time co
existence is not a trivial | |
193 implementation task. To achieve this goal we required a small | |
194 extension to the GNU C++ compiler (described in the GCC Manual for | |
195 C++ Extensions, see <a class="ulink" href="http://gcc.gnu.org/onlinedocs/gcc/S
trong-Using.html" target="_top">strong | |
196 using</a>), and a complex organization of debug- and | |
197 release-modes. The end result is that we have achieved per-use | |
198 recompilation but have had to give up some checking of the | |
199 <code class="code">std::basic_string</code> class template (namely, safe | |
200 iterators). | |
201 </p><div class="sect4" lang="en" xml:lang="en"><div class="titlepage"><div><div>
<h5 class="title"><a id="methods.coexistence.compile"></a>Compile-time coexisten
ce of release- and debug-mode components</h5></div></div></div><p>Both the relea
se-mode components and the debug-mode | |
202 components need to exist within a single translation unit so that | |
203 the debug versions can wrap the release versions. However, only one | |
204 of these components should be user-visible at any particular | |
205 time with the standard name, e.g., <code class="code">std::list</code>. </p><p
>In release mode, we define only the release-mode version of the | |
206 component with its standard name and do not include the debugging | |
207 component at all. The release mode version is defined within the | |
208 namespace <code class="code">std</code>. Minus the namespace associations, thi
s | |
209 method leaves the behavior of release mode completely unchanged from | |
210 its behavior prior to the introduction of the libstdc++ debug | |
211 mode. Here's an example of what this ends up looking like, in | |
212 C++.</p><pre class="programlisting"> | |
213 namespace std | |
214 { | |
215 template<typename _Tp, typename _Alloc = allocator<_Tp> > | |
216 class list | |
217 { | |
218 // ... | |
219 }; | |
220 } // namespace std | |
221 </pre><p>In debug mode we include the release-mode container (which is now | |
222 defined in in the namespace <code class="code">__norm</code>) and also the | |
223 debug-mode container. The debug-mode container is defined within the | |
224 namespace <code class="code">__debug</code>, which is associated with namespace | |
225 <code class="code">std</code> via the GNU namespace association extension. This | |
226 method allows the debug and release versions of the same component to | |
227 coexist at compile-time and link-time without causing an unreasonable | |
228 maintenance burden, while minimizing confusion. Again, this boils down | |
229 to C++ code as follows:</p><pre class="programlisting"> | |
230 namespace std | |
231 { | |
232 namespace __norm | |
233 { | |
234 template<typename _Tp, typename _Alloc = allocator<_Tp> > | |
235 class list | |
236 { | |
237 // ... | |
238 }; | |
239 } // namespace __gnu_norm | |
240 | |
241 namespace __debug | |
242 { | |
243 template<typename _Tp, typename _Alloc = allocator<_Tp> > | |
244 class list | |
245 : public __norm::list<_Tp, _Alloc>, | |
246 public __gnu_debug::_Safe_sequence<list<_Tp, _Alloc> > | |
247 { | |
248 // ... | |
249 }; | |
250 } // namespace __norm | |
251 | |
252 using namespace __debug __attribute__ ((strong)); | |
253 } | |
254 </pre></div><div class="sect4" lang="en" xml:lang="en"><div class="titlepage"><d
iv><div><h5 class="title"><a id="methods.coexistence.link"></a>Link- and run-tim
e coexistence of release- and | |
255 debug-mode components</h5></div></div></div><p>Because each component has a
distinct and separate release and | |
256 debug implementation, there are are no issues with link-time | |
257 coexistence: the separate namespaces result in different mangled | |
258 names, and thus unique linkage.</p><p>However, components that are defined and u
sed within the C++ | |
259 standard library itself face additional constraints. For instance, | |
260 some of the member functions of <code class="code"> std::moneypunct</code> retur
n | |
261 <code class="code">std::basic_string</code>. Normally, this is not a problem, bu
t | |
262 with a mixed mode standard library that could be using either | |
263 debug-mode or release-mode <code class="code"> basic_string</code> objects, thin
gs | |
264 get more complicated. As the return value of a function is not | |
265 encoded into the mangled name, there is no way to specify a | |
266 release-mode or a debug-mode string. In practice, this results in | |
267 runtime errors. A simplified example of this problem is as follows. | |
268 </p><p> Take this translation unit, compiled in debug-mode: </p><pre class="prog
ramlisting"> | |
269 // -D_GLIBCXX_DEBUG | |
270 #include <string> | |
271 | |
272 std::string test02(); | |
273 | |
274 std::string test01() | |
275 { | |
276 return test02(); | |
277 } | |
278 | |
279 int main() | |
280 { | |
281 test01(); | |
282 return 0; | |
283 } | |
284 </pre><p> ... and linked to this translation unit, compiled in release mode:</p>
<pre class="programlisting"> | |
285 #include <string> | |
286 | |
287 std::string | |
288 test02() | |
289 { | |
290 return std::string("toast"); | |
291 } | |
292 </pre><p> For this reason we cannot easily provide safe iterators for | |
293 the <code class="code">std::basic_string</code> class template, as it is prese
nt | |
294 throughout the C++ standard library. For instance, locale facets | |
295 define typedefs that include <code class="code">basic_string</code>: in a mixe
d | |
296 debug/release program, should that typedef be based on the | |
297 debug-mode <code class="code">basic_string</code> or the | |
298 release-mode <code class="code">basic_string</code>? While the answer could be | |
299 "both", and the difference hidden via renaming a la the | |
300 debug/release containers, we must note two things about locale | |
301 facets:</p><div class="orderedlist"><ol type="1"><li><p>They exist as shared s
tate: one can create a facet in one | |
302 translation unit and access the facet via the same type name in a | |
303 different translation unit. This means that we cannot have two | |
304 different versions of locale facets, because the types would not be | |
305 the same across debug/release-mode translation unit barriers.</p></li><li><p>T
hey have virtual functions returning strings: these functions | |
306 mangle in the same way regardless of the mangling of their return | |
307 types (see above), and their precise signatures can be relied upon | |
308 by users because they may be overridden in derived classes.</p></li></ol></div
><p>With the design of libstdc++ debug mode, we cannot effectively hide | |
309 the differences between debug and release-mode strings from the | |
310 user. Failure to hide the differences may result in unpredictable | |
311 behavior, and for this reason we have opted to only | |
312 perform <code class="code">basic_string</code> changes that do not require ABI | |
313 changes. The effect on users is expected to be minimal, as there are | |
314 simple alternatives (e.g., <code class="code">__gnu_debug::basic_string</code>
), | |
315 and the usability benefit we gain from the ability to mix debug- and | |
316 release-compiled translation units is enormous.</p></div><div class="sect4" la
ng="en" xml:lang="en"><div class="titlepage"><div><div><h5 class="title"><a id="
methods.coexistence.alt"></a>Alternatives for Coexistence</h5></div></div></div>
<p>The coexistence scheme above was chosen over many alternatives, | |
317 including language-only solutions and solutions that also required | |
318 extensions to the C++ front end. The following is a partial list of | |
319 solutions, with justifications for our rejection of each.</p><div class="itemi
zedlist"><ul type="disc"><li><p><span class="emphasis"><em>Completely separate d
ebug/release libraries</em></span>: This is by | |
320 far the simplest implementation option, where we do not allow any | |
321 coexistence of debug- and release-compiled translation units in a | |
322 program. This solution has an extreme negative affect on usability, | |
323 because it is quite likely that some libraries an application | |
324 depends on cannot be recompiled easily. This would not meet | |
325 our <span class="emphasis"><em>usability</em></span> or <span class="emphasis"
><em>minimize recompilation</em></span> criteria | |
326 well.</p></li><li><p><span class="emphasis"><em>Add a <code class="code">Debug
</code> boolean template parameter</em></span>: | |
327 Partial specialization could be used to select the debug | |
328 implementation when <code class="code">Debug == true</code>, and the state | |
329 of <code class="code">_GLIBCXX_DEBUG</code> could decide whether the | |
330 default <code class="code">Debug</code> argument is <code class="code">true</c
ode> | |
331 or <code class="code">false</code>. This option would break conformance with t
he | |
332 C++ standard in both debug <span class="emphasis"><em>and</em></span> release
modes. This would | |
333 not meet our <span class="emphasis"><em>correctness</em></span> criteria. </p>
</li><li><p><span class="emphasis"><em>Packaging a debug flag in the allocators<
/em></span>: We could | |
334 reuse the <code class="code">Allocator</code> template parameter of containe
rs | |
335 by adding a sentinel wrapper <code class="code">debug<></code> that | |
336 signals the user's intention to use debugging, and pick up | |
337 the <code class="code">debug<></code> allocator wrapper in a partial | |
338 specialization. However, this has two drawbacks: first, there is a | |
339 conformance issue because the default allocator would not be the | |
340 standard-specified <code class="code">std::allocator<T></code>. Second
ly | |
341 (and more importantly), users that specify allocators instead of | |
342 implicitly using the default allocator would not get debugging | |
343 containers. Thus this solution fails the <span class="emphasis"><em>correctn
ess</em></span> | |
344 criteria.</p></li><li><p><span class="emphasis"><em>Define debug containers
in another namespace, and employ | |
345 a <code class="code">using</code> declaration (or directive)</em></span>:
This is an | |
346 enticing option, because it would eliminate the need for | |
347 the <code class="code">link_name</code> extension by aliasing the | |
348 templates. However, there is no true template aliasing mechanism | |
349 is C++, because both <code class="code">using</code> directives and using | |
350 declarations disallow specialization. This method fails | |
351 the <span class="emphasis"><em>correctness</em></span> criteria.</p></li><
li><p><span class="emphasis"><em> Use implementation-specific properties of anon
ymous | |
352 namespaces. </em></span> | |
353 See <a class="ulink" href="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00004.
html" target="_top"> this post | |
354 </a> | |
355 This method fails the <span class="emphasis"><em>correctness</em></span> cri
teria.</p></li><li><p><span class="emphasis"><em>Extension: allow reopening on n
amespaces</em></span>: This would | |
356 allow the debug mode to effectively alias the | |
357 namespace <code class="code">std</code> to an internal namespace, such | |
358 as <code class="code">__gnu_std_debug</code>, so that it is completely | |
359 separate from the release-mode <code class="code">std</code> namespace. Whil
e | |
360 this will solve some renaming problems and ensure that | |
361 debug- and release-compiled code cannot be mixed unsafely, it ensures that | |
362 debug- and release-compiled code cannot be mixed at all. For | |
363 instance, the program would have two <code class="code">std::cout</code> | |
364 objects! This solution would fails the <span class="emphasis"><em>minimize | |
365 recompilation</em></span> requirement, because we would only be able to | |
366 support option (1) or (2).</p></li><li><p><span class="emphasis"><em>Extensi
on: use link name</em></span>: This option involves | |
367 complicated re-naming between debug-mode and release-mode | |
368 components at compile time, and then a g++ extension called <span class="emp
hasis"><em> | |
369 link name </em></span> to recover the original names at link time. There | |
370 are two drawbacks to this approach. One, it's very verbose, | |
371 relying on macro renaming at compile time and several levels of | |
372 include ordering. Two, ODR issues remained with container member | |
373 functions taking no arguments in mixed-mode settings resulting in | |
374 equivalent link names, <code class="code"> vector::push_back() </code> being | |
375 one example. | |
376 See <a class="ulink" href="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00177.
html" target="_top">link | |
377 name</a> </p></li></ul></div><p>Other options may exist for implementing the
debug mode, many of | |
378 which have probably been considered and others that may still be | |
379 lurking. This list may be expanded over time to include other | |
380 options that we could have implemented, but in all cases the full | |
381 ramifications of the approach (as measured against the design goals | |
382 for a libstdc++ debug mode) should be considered first. The DejaGNU | |
383 testsuite includes some testcases that check for known problems with | |
384 some solutions (e.g., the <code class="code">using</code> declaration solution | |
385 that breaks user specialization), and additional testcases will be | |
386 added as we are able to identify other typical problem cases. These | |
387 test cases will serve as a benchmark by which we can compare debug | |
388 mode implementations.</p></div></div></div><div class="sect2" lang="en" xml:la
ng="en"><div class="titlepage"><div><div><h3 class="title"><a id="manual.ext.deb
ug_mode.design.other"></a>Other Implementations</h3></div></div></div><p> | |
389 </p><p> There are several existing implementations of debug modes for C++ | |
390 standard library implementations, although none of them directly | |
391 supports debugging for programs using libstdc++. The existing | |
392 implementations include:</p><div class="itemizedlist"><ul type="disc"><li><p><
a class="ulink" href="http://www.mathcs.sjsu.edu/faculty/horstman/safestl.html"
target="_top">SafeSTL</a>: | |
393 SafeSTL was the original debugging version of the Standard Template | |
394 Library (STL), implemented by Cay S. Horstmann on top of the | |
395 Hewlett-Packard STL. Though it inspired much work in this area, it | |
396 has not been kept up-to-date for use with modern compilers or C++ | |
397 standard library implementations.</p></li><li><p><a class="ulink" href="http:/
/www.stlport.org/" target="_top">STLport</a>: STLport is a free | |
398 implementation of the C++ standard library derived from the <a class="ulink" h
ref="http://www.sgi.com/tech/stl/" target="_top">SGI implementation</a>, and | |
399 ported to many other platforms. It includes a debug mode that uses a | |
400 wrapper model (that in some way inspired the libstdc++ debug mode | |
401 design), although at the time of this writing the debug mode is | |
402 somewhat incomplete and meets only the "Full user recompilation" (2) | |
403 recompilation guarantee by requiring the user to link against a | |
404 different library in debug mode vs. release mode.</p></li><li><p><a class="uli
nk" href="http://www.metrowerks.com/mw/default.htm" target="_top">Metrowerks | |
405 CodeWarrior</a>: The C++ standard library that ships with Metrowerks | |
406 CodeWarrior includes a debug mode. It is a full debug-mode | |
407 implementation (including debugging for CodeWarrior extensions) and | |
408 is easy to use, although it meets only the "Full recompilation" (1) | |
409 recompilation guarantee.</p></li></ul></div></div></div><div class="navfooter"
><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align
="left"><a accesskey="p" href="bk01pt12ch30s03.html">Prev</a> </td><td width="20
%" align="center"><a accesskey="u" href="debug_mode.html">Up</a></td><td width="
40%" align="right"> <a accesskey="n" href="parallel_mode.html">Next</a></td></tr
><tr><td width="40%" align="left" valign="top">Using </td><td width="20%" align=
"center"><a accesskey="h" href="../spine.html">Home</a></td><td width="40%" alig
n="right" valign="top"> Chapter 31. Parallel Mode</td></tr></table></div></body>
</html> | |
OLD | NEW |