1 // Debugging mode support code -*- C++ -*-
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 // Free Software Foundation, Inc.
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)
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.
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.
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/>.
26 #include <debug/debug.h>
27 #include <debug/safe_sequence.h>
28 #include <debug/safe_iterator.h>
41 /** Returns different instances of __mutex depending on the passed address
42 * in order to limit contention without breaking current library binary
45 get_safe_base_mutex(void* __address
)
47 const size_t mask
= 0xf;
48 static __gnu_cxx::__mutex safe_base_mutex
[mask
+ 1];
49 const size_t index
= _Hash_impl::hash(__address
) & mask
;
50 return safe_base_mutex
[index
];
54 swap_seq(__gnu_debug::_Safe_sequence_base
& __lhs
,
55 __gnu_debug::_Safe_sequence_base
& __rhs
)
57 swap(__lhs
._M_iterators
, __rhs
._M_iterators
);
58 swap(__lhs
._M_const_iterators
, __rhs
._M_const_iterators
);
59 swap(__lhs
._M_version
, __rhs
._M_version
);
60 __gnu_debug::_Safe_iterator_base
* __iter
;
61 for (__iter
= __rhs
._M_iterators
; __iter
; __iter
= __iter
->_M_next
)
62 __iter
->_M_sequence
= &__rhs
;
63 for (__iter
= __lhs
._M_iterators
; __iter
; __iter
= __iter
->_M_next
)
64 __iter
->_M_sequence
= &__lhs
;
65 for (__iter
= __rhs
._M_const_iterators
; __iter
; __iter
= __iter
->_M_next
)
66 __iter
->_M_sequence
= &__rhs
;
67 for (__iter
= __lhs
._M_const_iterators
; __iter
; __iter
= __iter
->_M_next
)
68 __iter
->_M_sequence
= &__lhs
;
70 } // anonymous namespace
74 const char* _S_debug_messages
[] =
76 "function requires a valid iterator range [%1.name;, %2.name;)",
77 "attempt to insert into container with a singular iterator",
78 "attempt to insert into container with an iterator"
79 " from a different container",
80 "attempt to erase from container with a %2.state; iterator",
81 "attempt to erase from container with an iterator"
82 " from a different container",
83 "attempt to subscript container with out-of-bounds index %2;,"
84 " but container only holds %3; elements",
85 "attempt to access an element in an empty container",
86 "elements in iterator range [%1.name;, %2.name;)"
87 " are not partitioned by the value %3;",
88 "elements in iterator range [%1.name;, %2.name;)"
89 " are not partitioned by the predicate %3; and value %4;",
90 "elements in iterator range [%1.name;, %2.name;) are not sorted",
91 "elements in iterator range [%1.name;, %2.name;)"
92 " are not sorted according to the predicate %3;",
93 "elements in iterator range [%1.name;, %2.name;) do not form a heap",
94 "elements in iterator range [%1.name;, %2.name;)"
95 " do not form a heap with respect to the predicate %3;",
96 "attempt to write through a singular bitset reference",
97 "attempt to read from a singular bitset reference",
98 "attempt to flip a singular bitset reference",
99 "attempt to splice a list into itself",
100 "attempt to splice lists with inequal allocators",
101 "attempt to splice elements referenced by a %1.state; iterator",
102 "attempt to splice an iterator from a different container",
103 "splice destination %1.name;"
104 " occurs within source range [%2.name;, %3.name;)",
105 "attempt to initialize an iterator that will immediately become singular",
106 "attempt to copy-construct an iterator from a singular iterator",
107 "attempt to construct a constant iterator"
108 " from a singular mutable iterator",
109 "attempt to copy from a singular iterator",
110 "attempt to dereference a %1.state; iterator",
111 "attempt to increment a %1.state; iterator",
112 "attempt to decrement a %1.state; iterator",
113 "attempt to subscript a %1.state; iterator %2; step from"
114 " its current position, which falls outside its dereferenceable range",
115 "attempt to advance a %1.state; iterator %2; steps,"
116 " which falls outside its valid range",
117 "attempt to retreat a %1.state; iterator %2; steps,"
118 " which falls outside its valid range",
119 "attempt to compare a %1.state; iterator to a %2.state; iterator",
120 "attempt to compare iterators from different sequences",
121 "attempt to order a %1.state; iterator to a %2.state; iterator",
122 "attempt to order iterators from different sequences",
123 "attempt to compute the difference between a %1.state;"
124 " iterator to a %2.state; iterator",
125 "attempt to compute the different between two iterators"
126 " from different sequences",
127 "attempt to dereference an end-of-stream istream_iterator",
128 "attempt to increment an end-of-stream istream_iterator",
129 "attempt to output via an ostream_iterator with no associated stream",
130 "attempt to dereference an end-of-stream istreambuf_iterator"
131 " (this is a GNU extension)",
132 "attempt to increment an end-of-stream istreambuf_iterator",
133 "attempt to insert into container after an end iterator",
134 "attempt to erase from container after a %2.state; iterator not followed"
135 " by a dereferenceable one",
136 "function requires a valid iterator range (%2.name;, %3.name;)"
137 ", \"%2.name;\" shall be before and not equal to \"%3.name;\""
141 _Safe_sequence_base::
144 __gnu_cxx::__scoped_lock
sentry(_M_get_mutex());
145 for (_Safe_iterator_base
* __iter
= _M_iterators
; __iter
;)
147 _Safe_iterator_base
* __old
= __iter
;
148 __iter
= __iter
->_M_next
;
153 for (_Safe_iterator_base
* __iter2
= _M_const_iterators
; __iter2
;)
155 _Safe_iterator_base
* __old
= __iter2
;
156 __iter2
= __iter2
->_M_next
;
159 _M_const_iterators
= 0;
163 _Safe_sequence_base::
166 __gnu_cxx::__scoped_lock
sentry(_M_get_mutex());
167 for (_Safe_iterator_base
* __iter
= _M_iterators
; __iter
;)
169 _Safe_iterator_base
* __old
= __iter
;
170 __iter
= __iter
->_M_next
;
171 if (__old
->_M_singular())
172 __old
->_M_detach_single();
175 for (_Safe_iterator_base
* __iter2
= _M_const_iterators
; __iter2
;)
177 _Safe_iterator_base
* __old
= __iter2
;
178 __iter2
= __iter2
->_M_next
;
179 if (__old
->_M_singular())
180 __old
->_M_detach_single();
185 _Safe_sequence_base::
186 _M_revalidate_singular()
188 __gnu_cxx::__scoped_lock
sentry(_M_get_mutex());
189 for (_Safe_iterator_base
* __iter
= _M_iterators
; __iter
;
190 __iter
= __iter
->_M_next
)
191 __iter
->_M_version
= _M_version
;
193 for (_Safe_iterator_base
* __iter2
= _M_const_iterators
; __iter2
;
194 __iter2
= __iter2
->_M_next
)
195 __iter2
->_M_version
= _M_version
;
199 _Safe_sequence_base::
200 _M_swap(_Safe_sequence_base
& __x
)
202 // We need to lock both sequences to swap
203 using namespace __gnu_cxx
;
204 __mutex
*__this_mutex
= &_M_get_mutex();
205 __mutex
*__x_mutex
= &__x
._M_get_mutex();
206 if (__this_mutex
== __x_mutex
)
208 __scoped_lock
__lock(*__this_mutex
);
209 swap_seq(*this, __x
);
213 __scoped_lock
__l1(__this_mutex
< __x_mutex
214 ? *__this_mutex
: *__x_mutex
);
215 __scoped_lock
__l2(__this_mutex
< __x_mutex
216 ? *__x_mutex
: *__this_mutex
);
217 swap_seq(*this, __x
);
222 _Safe_sequence_base::
223 _M_get_mutex() throw ()
224 { return get_safe_base_mutex(this); }
227 _Safe_sequence_base::
228 _M_attach(_Safe_iterator_base
* __it
, bool __constant
)
230 __gnu_cxx::__scoped_lock
sentry(_M_get_mutex());
231 _M_attach_single(__it
, __constant
);
235 _Safe_sequence_base::
236 _M_attach_single(_Safe_iterator_base
* __it
, bool __constant
) throw ()
238 _Safe_iterator_base
*& __its
=
239 __constant
? _M_const_iterators
: _M_iterators
;
240 __it
->_M_next
= __its
;
242 __it
->_M_next
->_M_prior
= __it
;
247 _Safe_sequence_base::
248 _M_detach(_Safe_iterator_base
* __it
)
250 // Remove __it from this sequence's list
251 __gnu_cxx::__scoped_lock
sentry(_M_get_mutex());
252 _M_detach_single(__it
);
256 _Safe_sequence_base::
257 _M_detach_single(_Safe_iterator_base
* __it
) throw ()
259 // Remove __it from this sequence's list
261 if (_M_const_iterators
== __it
)
262 _M_const_iterators
= __it
->_M_next
;
263 if (_M_iterators
== __it
)
264 _M_iterators
= __it
->_M_next
;
268 _Safe_iterator_base::
269 _M_attach(_Safe_sequence_base
* __seq
, bool __constant
)
273 // Attach to the new sequence (if there is one)
277 _M_version
= _M_sequence
->_M_version
;
278 _M_sequence
->_M_attach(this, __constant
);
283 _Safe_iterator_base::
284 _M_attach_single(_Safe_sequence_base
* __seq
, bool __constant
) throw ()
288 // Attach to the new sequence (if there is one)
292 _M_version
= _M_sequence
->_M_version
;
293 _M_sequence
->_M_attach_single(this, __constant
);
298 _Safe_iterator_base::
303 _M_sequence
->_M_detach(this);
310 _Safe_iterator_base::
311 _M_detach_single() throw ()
315 _M_sequence
->_M_detach_single(this);
322 _Safe_iterator_base::
332 _Safe_iterator_base::
333 _M_singular() const throw ()
334 { return !_M_sequence
|| _M_version
!= _M_sequence
->_M_version
; }
337 _Safe_iterator_base::
338 _M_can_compare(const _Safe_iterator_base
& __x
) const throw ()
340 return (!_M_singular()
341 && !__x
._M_singular() && _M_sequence
== __x
._M_sequence
);
345 _Safe_iterator_base::
346 _M_get_mutex() throw ()
347 { return get_safe_base_mutex(_M_sequence
); }
350 _Error_formatter::_Parameter::
351 _M_print_field(const _Error_formatter
* __formatter
, const char* __name
) const
353 assert(this->_M_kind
!= _Parameter::__unused_param
);
354 const int __bufsize
= 64;
355 char __buf
[__bufsize
];
357 if (_M_kind
== __iterator
)
359 if (strcmp(__name
, "name") == 0)
361 assert(_M_variant
._M_iterator
._M_name
);
362 __formatter
->_M_print_word(_M_variant
._M_iterator
._M_name
);
364 else if (strcmp(__name
, "address") == 0)
366 __formatter
->_M_format_word(__buf
, __bufsize
, "%p",
367 _M_variant
._M_iterator
._M_address
);
368 __formatter
->_M_print_word(__buf
);
370 else if (strcmp(__name
, "type") == 0)
372 if (!_M_variant
._M_iterator
._M_type
)
373 __formatter
->_M_print_word("<unknown type>");
376 __formatter
->_M_print_word(_M_variant
._M_iterator
.
379 else if (strcmp(__name
, "constness") == 0)
381 static const char* __constness_names
[__last_constness
] =
387 __formatter
->_M_print_word(__constness_names
[_M_variant
.
391 else if (strcmp(__name
, "state") == 0)
393 static const char* __state_names
[__last_state
] =
397 "dereferenceable (start-of-sequence)",
402 __formatter
->_M_print_word(__state_names
[_M_variant
.
403 _M_iterator
._M_state
]);
405 else if (strcmp(__name
, "sequence") == 0)
407 assert(_M_variant
._M_iterator
._M_sequence
);
408 __formatter
->_M_format_word(__buf
, __bufsize
, "%p",
409 _M_variant
._M_iterator
._M_sequence
);
410 __formatter
->_M_print_word(__buf
);
412 else if (strcmp(__name
, "seq_type") == 0)
414 if (!_M_variant
._M_iterator
._M_seq_type
)
415 __formatter
->_M_print_word("<unknown seq_type>");
418 __formatter
->_M_print_word(_M_variant
._M_iterator
.
419 _M_seq_type
->name());
424 else if (_M_kind
== __sequence
)
426 if (strcmp(__name
, "name") == 0)
428 assert(_M_variant
._M_sequence
._M_name
);
429 __formatter
->_M_print_word(_M_variant
._M_sequence
._M_name
);
431 else if (strcmp(__name
, "address") == 0)
433 assert(_M_variant
._M_sequence
._M_address
);
434 __formatter
->_M_format_word(__buf
, __bufsize
, "%p",
435 _M_variant
._M_sequence
._M_address
);
436 __formatter
->_M_print_word(__buf
);
438 else if (strcmp(__name
, "type") == 0)
440 if (!_M_variant
._M_sequence
._M_type
)
441 __formatter
->_M_print_word("<unknown type>");
444 __formatter
->_M_print_word(_M_variant
._M_sequence
.
450 else if (_M_kind
== __integer
)
452 if (strcmp(__name
, "name") == 0)
454 assert(_M_variant
._M_integer
._M_name
);
455 __formatter
->_M_print_word(_M_variant
._M_integer
._M_name
);
460 else if (_M_kind
== __string
)
462 if (strcmp(__name
, "name") == 0)
464 assert(_M_variant
._M_string
._M_name
);
465 __formatter
->_M_print_word(_M_variant
._M_string
._M_name
);
477 _Error_formatter::_Parameter::
478 _M_print_description(const _Error_formatter
* __formatter
) const
480 const int __bufsize
= 128;
481 char __buf
[__bufsize
];
483 if (_M_kind
== __iterator
)
485 __formatter
->_M_print_word("iterator ");
486 if (_M_variant
._M_iterator
._M_name
)
488 __formatter
->_M_format_word(__buf
, __bufsize
, "\"%s\" ",
489 _M_variant
._M_iterator
._M_name
);
490 __formatter
->_M_print_word(__buf
);
493 __formatter
->_M_format_word(__buf
, __bufsize
, "@ 0x%p {\n",
494 _M_variant
._M_iterator
._M_address
);
495 __formatter
->_M_print_word(__buf
);
496 if (_M_variant
._M_iterator
._M_type
)
498 __formatter
->_M_print_word("type = ");
499 _M_print_field(__formatter
, "type");
501 if (_M_variant
._M_iterator
._M_constness
!= __unknown_constness
)
503 __formatter
->_M_print_word(" (");
504 _M_print_field(__formatter
, "constness");
505 __formatter
->_M_print_word(" iterator)");
507 __formatter
->_M_print_word(";\n");
510 if (_M_variant
._M_iterator
._M_state
!= __unknown_state
)
512 __formatter
->_M_print_word(" state = ");
513 _M_print_field(__formatter
, "state");
514 __formatter
->_M_print_word(";\n");
517 if (_M_variant
._M_iterator
._M_sequence
)
519 __formatter
->_M_print_word(" references sequence ");
520 if (_M_variant
._M_iterator
._M_seq_type
)
522 __formatter
->_M_print_word("with type `");
523 _M_print_field(__formatter
, "seq_type");
524 __formatter
->_M_print_word("' ");
527 __formatter
->_M_format_word(__buf
, __bufsize
, "@ 0x%p\n",
528 _M_variant
._M_sequence
._M_address
);
529 __formatter
->_M_print_word(__buf
);
531 __formatter
->_M_print_word("}\n");
533 else if (_M_kind
== __sequence
)
535 __formatter
->_M_print_word("sequence ");
536 if (_M_variant
._M_sequence
._M_name
)
538 __formatter
->_M_format_word(__buf
, __bufsize
, "\"%s\" ",
539 _M_variant
._M_sequence
._M_name
);
540 __formatter
->_M_print_word(__buf
);
543 __formatter
->_M_format_word(__buf
, __bufsize
, "@ 0x%p {\n",
544 _M_variant
._M_sequence
._M_address
);
545 __formatter
->_M_print_word(__buf
);
547 if (_M_variant
._M_sequence
._M_type
)
549 __formatter
->_M_print_word(" type = ");
550 _M_print_field(__formatter
, "type");
551 __formatter
->_M_print_word(";\n");
553 __formatter
->_M_print_word("}\n");
557 const _Error_formatter
&
558 _Error_formatter::_M_message(_Debug_msg_id __id
) const throw ()
559 { return this->_M_message(_S_debug_messages
[__id
]); }
562 _Error_formatter::_M_error() const
564 const int __bufsize
= 128;
565 char __buf
[__bufsize
];
567 // Emit file & line number information
572 _M_format_word(__buf
, __bufsize
, "%s:", _M_file
);
573 _M_print_word(__buf
);
574 _M_column
+= strlen(__buf
);
579 _M_format_word(__buf
, __bufsize
, "%u:", _M_line
);
580 _M_print_word(__buf
);
581 _M_column
+= strlen(__buf
);
586 _M_print_word("error: ");
588 // Print the error message
590 _M_print_string(_M_text
);
591 _M_print_word(".\n");
593 // Emit descriptions of the objects involved in the operation
595 bool __has_noninteger_parameters
= false;
596 for (unsigned int __i
= 0; __i
< _M_num_parameters
; ++__i
)
598 if (_M_parameters
[__i
]._M_kind
== _Parameter::__iterator
599 || _M_parameters
[__i
]._M_kind
== _Parameter::__sequence
)
601 if (!__has_noninteger_parameters
)
603 _M_first_line
= true;
604 _M_print_word("\nObjects involved in the operation:\n");
605 __has_noninteger_parameters
= true;
607 _M_parameters
[__i
]._M_print_description(this);
614 template<typename _Tp
>
616 _Error_formatter::_M_format_word(char* __buf
,
617 int __n
__attribute__ ((__unused__
)),
618 const char* __fmt
, _Tp __s
) const throw ()
620 #ifdef _GLIBCXX_USE_C99
621 std::snprintf(__buf
, __n
, __fmt
, __s
);
623 std::sprintf(__buf
, __fmt
, __s
);
629 _Error_formatter::_M_print_word(const char* __word
) const
633 fprintf(stderr
, "%s", __word
);
637 size_t __length
= strlen(__word
);
641 if ((_M_column
+ __length
< _M_max_length
)
642 || (__length
>= _M_max_length
&& _M_column
== 1))
644 // If this isn't the first line, indent
645 if (_M_column
== 1 && !_M_first_line
)
647 char __spacing
[_M_indent
+ 1];
648 for (int i
= 0; i
< _M_indent
; ++i
)
650 __spacing
[_M_indent
] = '\0';
651 fprintf(stderr
, "%s", __spacing
);
652 _M_column
+= _M_indent
;
655 fprintf(stderr
, "%s", __word
);
656 _M_column
+= __length
;
658 if (__word
[__length
- 1] == '\n')
660 _M_first_line
= false;
668 _M_print_word(__word
);
674 _M_print_string(const char* __string
) const
676 const char* __start
= __string
;
677 const char* __finish
= __start
;
678 const int __bufsize
= 128;
679 char __buf
[__bufsize
];
685 // [__start, __finish) denotes the next word
687 while (isalnum(*__finish
))
689 if (__start
== __finish
)
691 if (isspace(*__finish
))
694 const ptrdiff_t __len
= __finish
- __start
;
695 assert(__len
< __bufsize
);
696 memcpy(__buf
, __start
, __len
);
698 _M_print_word(__buf
);
701 // Skip extra whitespace
702 while (*__start
== ' ')
717 // Get the parameter number
718 assert(*__start
>= '1' && *__start
<= '9');
719 size_t __param
= *__start
- '0';
721 assert(__param
< _M_num_parameters
);
723 // '.' separates the parameter number from the field
724 // name, if there is one.
728 assert(*__start
== ';');
731 if (_M_parameters
[__param
]._M_kind
== _Parameter::__integer
)
733 _M_format_word(__buf
, __bufsize
, "%ld",
734 _M_parameters
[__param
]._M_variant
._M_integer
._M_value
);
735 _M_print_word(__buf
);
737 else if (_M_parameters
[__param
]._M_kind
== _Parameter::__string
)
738 _M_print_string(_M_parameters
[__param
]._M_variant
._M_string
._M_value
);
742 // Extract the field name we want
743 enum { __max_field_len
= 16 };
744 char __field
[__max_field_len
];
747 while (*__start
!= ';')
750 assert(__field_idx
< __max_field_len
-1);
751 __field
[__field_idx
++] = *__start
++;
754 __field
[__field_idx
] = 0;
756 _M_parameters
[__param
]._M_print_field(this, __field
);
761 _Error_formatter::_M_get_max_length() const throw ()
763 const char* __nptr
= std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH");
767 const unsigned long __ret
= std::strtoul(__nptr
, &__endptr
, 0);
768 if (*__nptr
!= '\0' && *__endptr
== '\0')
769 _M_max_length
= __ret
;
776 _Error_formatter::_M_format_word(char*, int, const char*,
781 _Error_formatter::_M_format_word(char*, int, const char*, long) const;
785 _Error_formatter::_M_format_word(char*, int, const char*,
790 _Error_formatter::_M_format_word(char*, int, const char*,
792 } // namespace __gnu_debug