OSDN Git Service

2010-09-29 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / src / debug.cc
1 // Debugging mode support code -*- C++ -*-
2
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
25
26 #include <debug/debug.h>
27 #include <debug/safe_sequence.h>
28 #include <debug/safe_iterator.h>
29 #include <algorithm>
30 #include <cassert>
31 #include <cstring>
32 #include <cctype>
33 #include <cstdio>
34 #include <cstdlib>
35
36 using namespace std;
37
38 namespace
39 {
40   __gnu_cxx::__mutex&
41   get_safe_base_mutex()
42   {
43     static __gnu_cxx::__mutex safe_base_mutex;
44     return safe_base_mutex;
45   }
46 } // anonymous namespace
47
48 namespace __gnu_debug
49 {
50   const char* _S_debug_messages[] = 
51   {
52     "function requires a valid iterator range [%1.name;, %2.name;)",
53     "attempt to insert into container with a singular iterator",
54     "attempt to insert into container with an iterator"
55     " from a different container",
56     "attempt to erase from container with a %2.state; iterator",
57     "attempt to erase from container with an iterator"
58     " from a different container",
59     "attempt to subscript container with out-of-bounds index %2;,"
60     " but container only holds %3; elements",
61     "attempt to access an element in an empty container",
62     "elements in iterator range [%1.name;, %2.name;)"
63     " are not partitioned by the value %3;",
64     "elements in iterator range [%1.name;, %2.name;)"
65     " are not partitioned by the predicate %3; and value %4;",
66     "elements in iterator range [%1.name;, %2.name;) are not sorted",
67     "elements in iterator range [%1.name;, %2.name;)"
68     " are not sorted according to the predicate %3;",
69     "elements in iterator range [%1.name;, %2.name;) do not form a heap",
70     "elements in iterator range [%1.name;, %2.name;)"
71     " do not form a heap with respect to the predicate %3;",
72     "attempt to write through a singular bitset reference",
73     "attempt to read from a singular bitset reference",
74     "attempt to flip a singular bitset reference",
75     "attempt to splice a list into itself",
76     "attempt to splice lists with inequal allocators",
77     "attempt to splice elements referenced by a %1.state; iterator",
78     "attempt to splice an iterator from a different container",
79     "splice destination %1.name;"
80     " occurs within source range [%2.name;, %3.name;)",
81     "attempt to initialize an iterator that will immediately become singular",
82     "attempt to copy-construct an iterator from a singular iterator",
83     "attempt to construct a constant iterator"
84     " from a singular mutable iterator",
85     "attempt to copy from a singular iterator",
86     "attempt to dereference a %1.state; iterator",
87     "attempt to increment a %1.state; iterator",
88     "attempt to decrement a %1.state; iterator",
89     "attempt to subscript a %1.state; iterator %2; step from"
90     " its current position, which falls outside its dereferenceable range",
91     "attempt to advance a %1.state; iterator %2; steps,"
92     " which falls outside its valid range",
93     "attempt to retreat a %1.state; iterator %2; steps,"
94     " which falls outside its valid range",
95     "attempt to compare a %1.state; iterator to a %2.state; iterator",
96     "attempt to compare iterators from different sequences",
97     "attempt to order a %1.state; iterator to a %2.state; iterator",
98     "attempt to order iterators from different sequences",
99     "attempt to compute the difference between a %1.state;"
100     " iterator to a %2.state; iterator",
101     "attempt to compute the different between two iterators"
102     " from different sequences",
103     "attempt to dereference an end-of-stream istream_iterator",
104     "attempt to increment an end-of-stream istream_iterator",
105     "attempt to output via an ostream_iterator with no associated stream",
106     "attempt to dereference an end-of-stream istreambuf_iterator"
107     " (this is a GNU extension)",
108     "attempt to increment an end-of-stream istreambuf_iterator",
109     "attempt to insert into container after an end iterator",
110     "attempt to erase from container after a %2.state; iterator not followed"
111     " by a dereferenceable one",
112     "function requires a valid iterator range (%1.name;, %2.name;)"
113     ", %1.name; shall not be equal to %2.name;"
114   };
115
116   void
117   _Safe_sequence_base::
118   _M_detach_all()
119   {
120     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
121     for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
122       {
123         _Safe_iterator_base* __old = __iter;
124         __iter = __iter->_M_next;
125         __old->_M_detach_single();
126       }
127     
128     for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
129       {
130         _Safe_iterator_base* __old = __iter2;
131         __iter2 = __iter2->_M_next;
132         __old->_M_detach_single();
133       }
134   }
135
136   void
137   _Safe_sequence_base::
138   _M_detach_singular()
139   {
140     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
141     for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
142       {
143         _Safe_iterator_base* __old = __iter;
144         __iter = __iter->_M_next;
145         if (__old->_M_singular())
146           __old->_M_detach_single();
147       }
148
149     for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
150       {
151         _Safe_iterator_base* __old = __iter2;
152         __iter2 = __iter2->_M_next;
153         if (__old->_M_singular())
154           __old->_M_detach_single();
155       }
156   }
157
158   void
159   _Safe_sequence_base::
160   _M_revalidate_singular()
161   {
162     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
163     for (_Safe_iterator_base* __iter = _M_iterators; __iter;
164          __iter = __iter->_M_next)
165       __iter->_M_version = _M_version;
166
167     for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;
168          __iter2 = __iter2->_M_next)
169       __iter2->_M_version = _M_version;
170   }
171
172   void
173   _Safe_sequence_base::
174   _M_swap(_Safe_sequence_base& __x)
175   {
176     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
177     swap(_M_iterators, __x._M_iterators);
178     swap(_M_const_iterators, __x._M_const_iterators);
179     swap(_M_version, __x._M_version);
180     _Safe_iterator_base* __iter;
181     for (__iter = _M_iterators; __iter; __iter = __iter->_M_next)
182       __iter->_M_sequence = this;
183     for (__iter = __x._M_iterators; __iter; __iter = __iter->_M_next)
184       __iter->_M_sequence = &__x;
185     for (__iter = _M_const_iterators; __iter; __iter = __iter->_M_next)
186       __iter->_M_sequence = this;
187     for (__iter = __x._M_const_iterators; __iter; __iter = __iter->_M_next)
188       __iter->_M_sequence = &__x;
189   }
190
191   __gnu_cxx::__mutex&
192   _Safe_sequence_base::
193   _M_get_mutex() throw ()
194   { return get_safe_base_mutex(); }
195
196   void
197   _Safe_iterator_base::
198   _M_attach(_Safe_sequence_base* __seq, bool __constant)
199   {
200     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
201     _M_attach_single(__seq, __constant);
202   }
203   
204   void
205   _Safe_iterator_base::
206   _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ()
207   {
208     _M_detach_single();
209     
210     // Attach to the new sequence (if there is one)
211     if (__seq)
212       {
213         _M_sequence = __seq;
214         _M_version = _M_sequence->_M_version;
215         _M_prior = 0;
216         if (__constant)
217           {
218             _M_next = _M_sequence->_M_const_iterators;
219             if (_M_next)
220               _M_next->_M_prior = this;
221             _M_sequence->_M_const_iterators = this;
222           }
223         else
224           {
225             _M_next = _M_sequence->_M_iterators;
226             if (_M_next)
227               _M_next->_M_prior = this;
228             _M_sequence->_M_iterators = this;
229           }
230       }
231   }
232
233   void
234   _Safe_iterator_base::
235   _M_detach()
236   {
237     __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
238     _M_detach_single();
239   }
240
241   void
242   _Safe_iterator_base::
243   _M_detach_single() throw ()
244   {
245     if (_M_sequence)
246       {
247         // Remove us from this sequence's list
248         if (_M_prior) 
249           _M_prior->_M_next = _M_next;
250         if (_M_next)  
251           _M_next->_M_prior = _M_prior;
252         
253         if (_M_sequence->_M_const_iterators == this)
254           _M_sequence->_M_const_iterators = _M_next;
255         if (_M_sequence->_M_iterators == this)
256           _M_sequence->_M_iterators = _M_next;
257       }
258
259     _M_sequence = 0;
260     _M_version = 0;
261     _M_prior = 0;
262     _M_next = 0;
263   }
264
265   bool
266   _Safe_iterator_base::
267   _M_singular() const throw ()
268   { return !_M_sequence || _M_version != _M_sequence->_M_version; }
269     
270   bool
271   _Safe_iterator_base::
272   _M_can_compare(const _Safe_iterator_base& __x) const throw ()
273   {
274     return (!_M_singular() 
275             && !__x._M_singular() && _M_sequence == __x._M_sequence);
276   }
277
278   __gnu_cxx::__mutex&
279   _Safe_iterator_base::
280   _M_get_mutex() throw ()
281   { return get_safe_base_mutex(); }
282
283   void
284   _Error_formatter::_Parameter::
285   _M_print_field(const _Error_formatter* __formatter, const char* __name) const
286   {
287     assert(this->_M_kind != _Parameter::__unused_param);
288     const int __bufsize = 64;
289     char __buf[__bufsize];
290     
291     if (_M_kind == __iterator)
292       {
293         if (strcmp(__name, "name") == 0)
294           {
295             assert(_M_variant._M_iterator._M_name);
296             __formatter->_M_print_word(_M_variant._M_iterator._M_name);
297           }
298         else if (strcmp(__name, "address") == 0)
299           {
300             __formatter->_M_format_word(__buf, __bufsize, "%p", 
301                                         _M_variant._M_iterator._M_address);
302             __formatter->_M_print_word(__buf);
303           }
304         else if (strcmp(__name, "type") == 0)
305           {
306             if (!_M_variant._M_iterator._M_type)
307               __formatter->_M_print_word("<unknown type>");
308             else
309               // TBD: demangle!
310               __formatter->_M_print_word(_M_variant._M_iterator.
311                                          _M_type->name());
312           }
313         else if (strcmp(__name, "constness") == 0)
314           {
315             static const char* __constness_names[__last_constness] =
316               {
317                 "<unknown>",
318                 "constant",
319                 "mutable"
320               };
321             __formatter->_M_print_word(__constness_names[_M_variant.
322                                                          _M_iterator.
323                                                          _M_constness]);
324           }
325         else if (strcmp(__name, "state") == 0)
326           {
327             static const char* __state_names[__last_state] = 
328               {
329                 "<unknown>",
330                 "singular",
331                 "dereferenceable (start-of-sequence)",
332                 "dereferenceable",
333                 "past-the-end",
334                 "before begin"
335               };
336             __formatter->_M_print_word(__state_names[_M_variant.
337                                                      _M_iterator._M_state]);
338           }
339         else if (strcmp(__name, "sequence") == 0)
340           {
341             assert(_M_variant._M_iterator._M_sequence);
342             __formatter->_M_format_word(__buf, __bufsize, "%p", 
343                                         _M_variant._M_iterator._M_sequence);
344             __formatter->_M_print_word(__buf);
345           }
346         else if (strcmp(__name, "seq_type") == 0)
347           {
348             if (!_M_variant._M_iterator._M_seq_type)
349               __formatter->_M_print_word("<unknown seq_type>");
350             else
351               // TBD: demangle!
352               __formatter->_M_print_word(_M_variant._M_iterator.
353                                          _M_seq_type->name());
354           }
355         else
356           assert(false);
357       }
358     else if (_M_kind == __sequence)
359       {
360         if (strcmp(__name, "name") == 0)
361           {
362             assert(_M_variant._M_sequence._M_name);
363             __formatter->_M_print_word(_M_variant._M_sequence._M_name);
364           }
365         else if (strcmp(__name, "address") == 0)
366           {
367             assert(_M_variant._M_sequence._M_address);
368             __formatter->_M_format_word(__buf, __bufsize, "%p", 
369                                         _M_variant._M_sequence._M_address);
370             __formatter->_M_print_word(__buf);
371           }
372         else if (strcmp(__name, "type") == 0)
373           {
374             if (!_M_variant._M_sequence._M_type)
375               __formatter->_M_print_word("<unknown type>");
376             else
377               // TBD: demangle!
378               __formatter->_M_print_word(_M_variant._M_sequence.
379                                          _M_type->name());
380           }
381         else
382           assert(false);
383       }
384     else if (_M_kind == __integer)
385       {
386         if (strcmp(__name, "name") == 0)
387           {
388             assert(_M_variant._M_integer._M_name);
389             __formatter->_M_print_word(_M_variant._M_integer._M_name);
390           }
391         else
392         assert(false);
393       }
394     else if (_M_kind == __string)
395       {
396         if (strcmp(__name, "name") == 0)
397           {
398             assert(_M_variant._M_string._M_name);
399             __formatter->_M_print_word(_M_variant._M_string._M_name);
400           }
401         else
402           assert(false);
403       }
404     else
405       {
406         assert(false);
407       }
408   }
409   
410   void
411   _Error_formatter::_Parameter::
412   _M_print_description(const _Error_formatter* __formatter) const
413   {
414     const int __bufsize = 128;
415     char __buf[__bufsize];
416     
417     if (_M_kind == __iterator)
418       {
419         __formatter->_M_print_word("iterator ");
420         if (_M_variant._M_iterator._M_name)
421           {
422             __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", 
423                                         _M_variant._M_iterator._M_name);
424             __formatter->_M_print_word(__buf);
425           }
426         
427         __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", 
428                                     _M_variant._M_iterator._M_address);
429         __formatter->_M_print_word(__buf);
430         if (_M_variant._M_iterator._M_type)
431           {
432             __formatter->_M_print_word("type = ");
433             _M_print_field(__formatter, "type");
434             
435             if (_M_variant._M_iterator._M_constness != __unknown_constness)
436               {
437                 __formatter->_M_print_word(" (");
438                 _M_print_field(__formatter, "constness");
439                 __formatter->_M_print_word(" iterator)");
440               }
441             __formatter->_M_print_word(";\n");
442           }
443         
444         if (_M_variant._M_iterator._M_state != __unknown_state)
445           {
446             __formatter->_M_print_word("  state = ");
447             _M_print_field(__formatter, "state");
448             __formatter->_M_print_word(";\n");
449           }
450         
451         if (_M_variant._M_iterator._M_sequence)
452           {
453             __formatter->_M_print_word("  references sequence ");
454             if (_M_variant._M_iterator._M_seq_type)
455               {
456                 __formatter->_M_print_word("with type `");
457                 _M_print_field(__formatter, "seq_type");
458                 __formatter->_M_print_word("' ");
459               }
460             
461             __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n", 
462                                         _M_variant._M_sequence._M_address);
463             __formatter->_M_print_word(__buf);
464           }
465         __formatter->_M_print_word("}\n");
466       }
467     else if (_M_kind == __sequence)
468       {
469         __formatter->_M_print_word("sequence ");
470         if (_M_variant._M_sequence._M_name)
471           {
472             __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", 
473                                         _M_variant._M_sequence._M_name);
474             __formatter->_M_print_word(__buf);
475           }
476         
477         __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", 
478                                     _M_variant._M_sequence._M_address);
479         __formatter->_M_print_word(__buf);
480         
481         if (_M_variant._M_sequence._M_type)
482           {
483             __formatter->_M_print_word("  type = ");
484             _M_print_field(__formatter, "type");
485             __formatter->_M_print_word(";\n");
486           }       
487         __formatter->_M_print_word("}\n");
488       }
489   }
490
491   const _Error_formatter&
492   _Error_formatter::_M_message(_Debug_msg_id __id) const throw ()
493   { return this->_M_message(_S_debug_messages[__id]); }
494   
495   void
496   _Error_formatter::_M_error() const
497   {
498     const int __bufsize = 128;
499     char __buf[__bufsize];
500     
501     // Emit file & line number information
502     _M_column = 1;
503     _M_wordwrap = false;
504     if (_M_file)
505       {
506         _M_format_word(__buf, __bufsize, "%s:", _M_file);
507         _M_print_word(__buf);
508         _M_column += strlen(__buf);
509       }
510     
511     if (_M_line > 0)
512       {
513         _M_format_word(__buf, __bufsize, "%u:", _M_line);
514         _M_print_word(__buf);
515         _M_column += strlen(__buf);
516       }
517     
518     if (_M_max_length)
519       _M_wordwrap = true;
520     _M_print_word("error: ");
521     
522     // Print the error message
523     assert(_M_text);
524     _M_print_string(_M_text);
525     _M_print_word(".\n");
526     
527     // Emit descriptions of the objects involved in the operation
528     _M_wordwrap = false;
529     bool __has_noninteger_parameters = false;
530     for (unsigned int __i = 0; __i < _M_num_parameters; ++__i)
531       {
532         if (_M_parameters[__i]._M_kind == _Parameter::__iterator
533             || _M_parameters[__i]._M_kind == _Parameter::__sequence)
534           {
535             if (!__has_noninteger_parameters)
536               {
537                 _M_first_line = true;
538                 _M_print_word("\nObjects involved in the operation:\n");
539                 __has_noninteger_parameters = true;
540               }
541             _M_parameters[__i]._M_print_description(this);
542           }
543       }
544     
545     abort();
546   }
547
548   template<typename _Tp>
549     void
550     _Error_formatter::_M_format_word(char* __buf, 
551                                      int __n __attribute__ ((__unused__)), 
552                                      const char* __fmt, _Tp __s) const throw ()
553     {
554 #ifdef _GLIBCXX_USE_C99
555       std::snprintf(__buf, __n, __fmt, __s);
556 #else
557       std::sprintf(__buf, __fmt, __s);
558 #endif
559     }
560
561   
562   void 
563   _Error_formatter::_M_print_word(const char* __word) const
564   {
565     if (!_M_wordwrap) 
566       {
567         fprintf(stderr, "%s", __word);
568         return;
569       }
570     
571     size_t __length = strlen(__word);
572     if (__length == 0)
573       return;
574     
575     if ((_M_column + __length < _M_max_length)
576         || (__length >= _M_max_length && _M_column == 1)) 
577       {
578         // If this isn't the first line, indent
579         if (_M_column == 1 && !_M_first_line)
580           {
581             char __spacing[_M_indent + 1];
582             for (int i = 0; i < _M_indent; ++i)
583               __spacing[i] = ' ';
584             __spacing[_M_indent] = '\0';
585             fprintf(stderr, "%s", __spacing);
586             _M_column += _M_indent;
587           }
588         
589         fprintf(stderr, "%s", __word);
590         _M_column += __length;
591         
592         if (__word[__length - 1] == '\n') 
593           {
594             _M_first_line = false;
595             _M_column = 1;
596           }
597       }
598     else
599       {
600         _M_column = 1;
601         _M_print_word("\n");
602         _M_print_word(__word);
603       }
604   }
605   
606   void
607   _Error_formatter::
608   _M_print_string(const char* __string) const
609   {
610     const char* __start = __string;
611     const char* __finish = __start;
612     const int __bufsize = 128;
613     char __buf[__bufsize];
614
615     while (*__start)
616       {
617         if (*__start != '%')
618           {
619             // [__start, __finish) denotes the next word
620             __finish = __start;
621             while (isalnum(*__finish))
622               ++__finish;
623             if (__start == __finish)
624               ++__finish;
625             if (isspace(*__finish))
626               ++__finish;
627             
628             const ptrdiff_t __len = __finish - __start;
629             assert(__len < __bufsize);
630             memcpy(__buf, __start, __len);
631             __buf[__len] = '\0';
632             _M_print_word(__buf);
633             __start = __finish;
634             
635             // Skip extra whitespace
636             while (*__start == ' ') 
637               ++__start;
638             
639             continue;
640           } 
641         
642         ++__start;
643         assert(*__start);
644         if (*__start == '%')
645           {
646             _M_print_word("%");
647             ++__start;
648             continue;
649           }
650         
651         // Get the parameter number
652         assert(*__start >= '1' && *__start <= '9');
653         size_t __param = *__start - '0';
654         --__param;
655         assert(__param < _M_num_parameters);
656       
657         // '.' separates the parameter number from the field
658         // name, if there is one.
659         ++__start;
660         if (*__start != '.')
661           {
662             assert(*__start == ';');
663             ++__start;
664             __buf[0] = '\0';
665             if (_M_parameters[__param]._M_kind == _Parameter::__integer)
666               {
667                 _M_format_word(__buf, __bufsize, "%ld", 
668                                _M_parameters[__param]._M_variant._M_integer._M_value);
669                 _M_print_word(__buf);
670               }
671             else if (_M_parameters[__param]._M_kind == _Parameter::__string)
672               _M_print_string(_M_parameters[__param]._M_variant._M_string._M_value);
673             continue;
674           }
675         
676         // Extract the field name we want
677         enum { __max_field_len = 16 };
678         char __field[__max_field_len];
679         int __field_idx = 0;
680         ++__start;
681         while (*__start != ';')
682           {
683             assert(*__start);
684             assert(__field_idx < __max_field_len-1);
685             __field[__field_idx++] = *__start++;
686           }
687         ++__start;
688         __field[__field_idx] = 0;
689         
690         _M_parameters[__param]._M_print_field(this, __field);             
691       }
692   }
693
694   void
695   _Error_formatter::_M_get_max_length() const throw ()
696   {
697     const char* __nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH");
698     if (__nptr)
699       {
700         char* __endptr;
701         const unsigned long __ret = std::strtoul(__nptr, &__endptr, 0);
702         if (*__nptr != '\0' && *__endptr == '\0')
703           _M_max_length = __ret;
704       }
705   }
706
707   // Instantiations.
708   template
709     void
710     _Error_formatter::_M_format_word(char*, int, const char*, 
711                                      const void*) const;
712
713   template
714     void
715     _Error_formatter::_M_format_word(char*, int, const char*, long) const;
716
717   template
718     void
719     _Error_formatter::_M_format_word(char*, int, const char*, 
720                                      std::size_t) const;
721
722   template
723     void
724     _Error_formatter::_M_format_word(char*, int, const char*, 
725                                      const char*) const;
726 } // namespace __gnu_debug