1 // Debugging mode support code -*- C++ -*-
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 // 2011 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_unordered_container.h>
29 #include <debug/safe_iterator.h>
30 #include <debug/safe_local_iterator.h>
43 /** Returns different instances of __mutex depending on the passed address
44 * in order to limit contention without breaking current library binary
47 get_safe_base_mutex(void* __address)
49 const size_t mask = 0xf;
50 static __gnu_cxx::__mutex safe_base_mutex[mask + 1];
51 const size_t index = _Hash_impl::hash(__address) & mask;
52 return safe_base_mutex[index];
56 swap_its(__gnu_debug::_Safe_sequence_base& __lhs,
57 __gnu_debug::_Safe_iterator_base*& __lhs_its,
58 __gnu_debug::_Safe_sequence_base& __rhs,
59 __gnu_debug::_Safe_iterator_base*& __rhs_its)
61 swap(__lhs_its, __rhs_its);
62 __gnu_debug::_Safe_iterator_base* __iter;
63 for (__iter = __rhs_its; __iter; __iter = __iter->_M_next)
64 __iter->_M_sequence = &__rhs;
65 for (__iter = __lhs_its; __iter; __iter = __iter->_M_next)
66 __iter->_M_sequence = &__lhs;
70 swap_seq(__gnu_debug::_Safe_sequence_base& __lhs,
71 __gnu_debug::_Safe_sequence_base& __rhs)
73 swap(__lhs._M_version, __rhs._M_version);
74 swap_its(__lhs, __lhs._M_iterators,
75 __rhs, __rhs._M_iterators);
76 swap_its(__lhs, __lhs._M_const_iterators,
77 __rhs, __rhs._M_const_iterators);
81 swap_ucont(__gnu_debug::_Safe_unordered_container_base& __lhs,
82 __gnu_debug::_Safe_unordered_container_base& __rhs)
84 swap_seq(__lhs, __rhs);
85 swap_its(__lhs, __lhs._M_local_iterators,
86 __rhs, __rhs._M_local_iterators);
87 swap_its(__lhs, __lhs._M_const_local_iterators,
88 __rhs, __rhs._M_const_local_iterators);
92 detach_all(__gnu_debug::_Safe_iterator_base* __iter)
96 __gnu_debug::_Safe_iterator_base* __old = __iter;
97 __iter = __iter->_M_next;
101 } // anonymous namespace
103 namespace __gnu_debug
105 const char* _S_debug_messages[] =
108 "function requires a valid iterator range [%1.name;, %2.name;)",
109 "attempt to insert into container with a singular iterator",
110 "attempt to insert into container with an iterator"
111 " from a different container",
112 "attempt to erase from container with a %2.state; iterator",
113 "attempt to erase from container with an iterator"
114 " from a different container",
115 "attempt to subscript container with out-of-bounds index %2;,"
116 " but container only holds %3; elements",
117 "attempt to access an element in an empty container",
118 "elements in iterator range [%1.name;, %2.name;)"
119 " are not partitioned by the value %3;",
120 "elements in iterator range [%1.name;, %2.name;)"
121 " are not partitioned by the predicate %3; and value %4;",
122 "elements in iterator range [%1.name;, %2.name;) are not sorted",
123 "elements in iterator range [%1.name;, %2.name;)"
124 " are not sorted according to the predicate %3;",
125 "elements in iterator range [%1.name;, %2.name;) do not form a heap",
126 "elements in iterator range [%1.name;, %2.name;)"
127 " do not form a heap with respect to the predicate %3;",
128 // std::bitset checks
129 "attempt to write through a singular bitset reference",
130 "attempt to read from a singular bitset reference",
131 "attempt to flip a singular bitset reference",
133 "attempt to splice a list into itself",
134 "attempt to splice lists with inequal allocators",
135 "attempt to splice elements referenced by a %1.state; iterator",
136 "attempt to splice an iterator from a different container",
137 "splice destination %1.name;"
138 " occurs within source range [%2.name;, %3.name;)",
140 "attempt to initialize an iterator that will immediately become singular",
141 "attempt to copy-construct an iterator from a singular iterator",
142 "attempt to construct a constant iterator"
143 " from a singular mutable iterator",
144 "attempt to copy from a singular iterator",
145 "attempt to dereference a %1.state; iterator",
146 "attempt to increment a %1.state; iterator",
147 "attempt to decrement a %1.state; iterator",
148 "attempt to subscript a %1.state; iterator %2; step from"
149 " its current position, which falls outside its dereferenceable range",
150 "attempt to advance a %1.state; iterator %2; steps,"
151 " which falls outside its valid range",
152 "attempt to retreat a %1.state; iterator %2; steps,"
153 " which falls outside its valid range",
154 "attempt to compare a %1.state; iterator to a %2.state; iterator",
155 "attempt to compare iterators from different sequences",
156 "attempt to order a %1.state; iterator to a %2.state; iterator",
157 "attempt to order iterators from different sequences",
158 "attempt to compute the difference between a %1.state;"
159 " iterator to a %2.state; iterator",
160 "attempt to compute the different between two iterators"
161 " from different sequences",
163 "attempt to dereference an end-of-stream istream_iterator",
164 "attempt to increment an end-of-stream istream_iterator",
166 "attempt to output via an ostream_iterator with no associated stream",
167 // istreambuf_iterator
168 "attempt to dereference an end-of-stream istreambuf_iterator"
169 " (this is a GNU extension)",
170 "attempt to increment an end-of-stream istreambuf_iterator",
172 "attempt to insert into container after an end iterator",
173 "attempt to erase from container after a %2.state; iterator not followed"
174 " by a dereferenceable one",
175 "function requires a valid iterator range (%2.name;, %3.name;)"
176 ", \"%2.name;\" shall be before and not equal to \"%3.name;\"",
177 // std::unordered_container::local_iterator
178 "attempt to compare local iterators from different unordered container"
183 _Safe_sequence_base::
186 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
187 detach_all(_M_iterators);
190 detach_all(_M_const_iterators);
191 _M_const_iterators = 0;
195 _Safe_sequence_base::
198 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
199 for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
201 _Safe_iterator_base* __old = __iter;
202 __iter = __iter->_M_next;
203 if (__old->_M_singular())
204 __old->_M_detach_single();
207 for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
209 _Safe_iterator_base* __old = __iter2;
210 __iter2 = __iter2->_M_next;
211 if (__old->_M_singular())
212 __old->_M_detach_single();
217 _Safe_sequence_base::
218 _M_revalidate_singular()
220 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
221 for (_Safe_iterator_base* __iter = _M_iterators; __iter;
222 __iter = __iter->_M_next)
223 __iter->_M_version = _M_version;
225 for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;
226 __iter2 = __iter2->_M_next)
227 __iter2->_M_version = _M_version;
231 _Safe_sequence_base::
232 _M_swap(_Safe_sequence_base& __x)
234 // We need to lock both sequences to swap
235 using namespace __gnu_cxx;
236 __mutex *__this_mutex = &_M_get_mutex();
237 __mutex *__x_mutex = &__x._M_get_mutex();
238 if (__this_mutex == __x_mutex)
240 __scoped_lock __lock(*__this_mutex);
241 swap_seq(*this, __x);
245 __scoped_lock __l1(__this_mutex < __x_mutex
246 ? *__this_mutex : *__x_mutex);
247 __scoped_lock __l2(__this_mutex < __x_mutex
248 ? *__x_mutex : *__this_mutex);
249 swap_seq(*this, __x);
254 _Safe_sequence_base::
255 _M_get_mutex() throw ()
256 { return get_safe_base_mutex(this); }
259 _Safe_sequence_base::
260 _M_attach(_Safe_iterator_base* __it, bool __constant)
262 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
263 _M_attach_single(__it, __constant);
267 _Safe_sequence_base::
268 _M_attach_single(_Safe_iterator_base* __it, bool __constant) throw ()
270 _Safe_iterator_base*& __its =
271 __constant ? _M_const_iterators : _M_iterators;
272 __it->_M_next = __its;
274 __it->_M_next->_M_prior = __it;
279 _Safe_sequence_base::
280 _M_detach(_Safe_iterator_base* __it)
282 // Remove __it from this sequence's list
283 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
284 _M_detach_single(__it);
288 _Safe_sequence_base::
289 _M_detach_single(_Safe_iterator_base* __it) throw ()
291 // Remove __it from this sequence's list
293 if (_M_const_iterators == __it)
294 _M_const_iterators = __it->_M_next;
295 if (_M_iterators == __it)
296 _M_iterators = __it->_M_next;
300 _Safe_iterator_base::
301 _M_attach(_Safe_sequence_base* __seq, bool __constant)
305 // Attach to the new sequence (if there is one)
309 _M_version = _M_sequence->_M_version;
310 _M_sequence->_M_attach(this, __constant);
315 _Safe_iterator_base::
316 _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ()
320 // Attach to the new sequence (if there is one)
324 _M_version = _M_sequence->_M_version;
325 _M_sequence->_M_attach_single(this, __constant);
330 _Safe_iterator_base::
334 _M_sequence->_M_detach(this);
340 _Safe_iterator_base::
341 _M_detach_single() throw ()
344 _M_sequence->_M_detach_single(this);
350 _Safe_iterator_base::
360 _Safe_iterator_base::
361 _M_singular() const throw ()
362 { return !_M_sequence || _M_version != _M_sequence->_M_version; }
365 _Safe_iterator_base::
366 _M_can_compare(const _Safe_iterator_base& __x) const throw ()
368 return (!_M_singular()
369 && !__x._M_singular() && _M_sequence == __x._M_sequence);
373 _Safe_iterator_base::
374 _M_get_mutex() throw ()
375 { return get_safe_base_mutex(_M_sequence); }
377 _Safe_unordered_container_base*
378 _Safe_local_iterator_base::
379 _M_get_container() const _GLIBCXX_NOEXCEPT
380 { return static_cast<_Safe_unordered_container_base*>(_M_sequence); }
383 _Safe_local_iterator_base::
384 _M_attach(_Safe_sequence_base* __cont, bool __constant)
388 // Attach to the new container (if there is one)
391 _M_sequence = __cont;
392 _M_version = _M_sequence->_M_version;
393 _M_get_container()->_M_attach_local(this, __constant);
398 _Safe_local_iterator_base::
399 _M_attach_single(_Safe_sequence_base* __cont, bool __constant) throw ()
403 // Attach to the new container (if there is one)
406 _M_sequence = __cont;
407 _M_version = _M_sequence->_M_version;
408 _M_get_container()->_M_attach_local_single(this, __constant);
413 _Safe_local_iterator_base::
417 _M_get_container()->_M_detach_local(this);
423 _Safe_local_iterator_base::
424 _M_detach_single() throw ()
427 _M_get_container()->_M_detach_local_single(this);
433 _Safe_unordered_container_base::
436 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
437 detach_all(_M_iterators);
440 detach_all(_M_const_iterators);
441 _M_const_iterators = 0;
443 detach_all(_M_local_iterators);
444 _M_local_iterators = 0;
446 detach_all(_M_const_local_iterators);
447 _M_const_local_iterators = 0;
451 _Safe_unordered_container_base::
452 _M_swap(_Safe_unordered_container_base& __x)
454 // We need to lock both containers to swap
455 using namespace __gnu_cxx;
456 __mutex *__this_mutex = &_M_get_mutex();
457 __mutex *__x_mutex = &__x._M_get_mutex();
458 if (__this_mutex == __x_mutex)
460 __scoped_lock __lock(*__this_mutex);
461 swap_ucont(*this, __x);
465 __scoped_lock __l1(__this_mutex < __x_mutex
466 ? *__this_mutex : *__x_mutex);
467 __scoped_lock __l2(__this_mutex < __x_mutex
468 ? *__x_mutex : *__this_mutex);
469 swap_ucont(*this, __x);
474 _Safe_unordered_container_base::
475 _M_attach_local(_Safe_iterator_base* __it, bool __constant)
477 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
478 _M_attach_local_single(__it, __constant);
482 _Safe_unordered_container_base::
483 _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw ()
485 _Safe_iterator_base*& __its =
486 __constant ? _M_const_local_iterators : _M_local_iterators;
487 __it->_M_next = __its;
489 __it->_M_next->_M_prior = __it;
494 _Safe_unordered_container_base::
495 _M_detach_local(_Safe_iterator_base* __it)
497 // Remove __it from this container's list
498 __gnu_cxx::__scoped_lock sentry(_M_get_mutex());
499 _M_detach_local_single(__it);
503 _Safe_unordered_container_base::
504 _M_detach_local_single(_Safe_iterator_base* __it) throw ()
506 // Remove __it from this container's list
508 if (_M_const_local_iterators == __it)
509 _M_const_local_iterators = __it->_M_next;
510 if (_M_local_iterators == __it)
511 _M_local_iterators = __it->_M_next;
515 _Error_formatter::_Parameter::
516 _M_print_field(const _Error_formatter* __formatter, const char* __name) const
518 assert(this->_M_kind != _Parameter::__unused_param);
519 const int __bufsize = 64;
520 char __buf[__bufsize];
522 if (_M_kind == __iterator)
524 if (strcmp(__name, "name") == 0)
526 assert(_M_variant._M_iterator._M_name);
527 __formatter->_M_print_word(_M_variant._M_iterator._M_name);
529 else if (strcmp(__name, "address") == 0)
531 __formatter->_M_format_word(__buf, __bufsize, "%p",
532 _M_variant._M_iterator._M_address);
533 __formatter->_M_print_word(__buf);
535 else if (strcmp(__name, "type") == 0)
537 if (!_M_variant._M_iterator._M_type)
538 __formatter->_M_print_word("<unknown type>");
541 __formatter->_M_print_word(_M_variant._M_iterator.
544 else if (strcmp(__name, "constness") == 0)
546 static const char* __constness_names[__last_constness] =
552 __formatter->_M_print_word(__constness_names[_M_variant.
556 else if (strcmp(__name, "state") == 0)
558 static const char* __state_names[__last_state] =
562 "dereferenceable (start-of-sequence)",
567 __formatter->_M_print_word(__state_names[_M_variant.
568 _M_iterator._M_state]);
570 else if (strcmp(__name, "sequence") == 0)
572 assert(_M_variant._M_iterator._M_sequence);
573 __formatter->_M_format_word(__buf, __bufsize, "%p",
574 _M_variant._M_iterator._M_sequence);
575 __formatter->_M_print_word(__buf);
577 else if (strcmp(__name, "seq_type") == 0)
579 if (!_M_variant._M_iterator._M_seq_type)
580 __formatter->_M_print_word("<unknown seq_type>");
583 __formatter->_M_print_word(_M_variant._M_iterator.
584 _M_seq_type->name());
589 else if (_M_kind == __sequence)
591 if (strcmp(__name, "name") == 0)
593 assert(_M_variant._M_sequence._M_name);
594 __formatter->_M_print_word(_M_variant._M_sequence._M_name);
596 else if (strcmp(__name, "address") == 0)
598 assert(_M_variant._M_sequence._M_address);
599 __formatter->_M_format_word(__buf, __bufsize, "%p",
600 _M_variant._M_sequence._M_address);
601 __formatter->_M_print_word(__buf);
603 else if (strcmp(__name, "type") == 0)
605 if (!_M_variant._M_sequence._M_type)
606 __formatter->_M_print_word("<unknown type>");
609 __formatter->_M_print_word(_M_variant._M_sequence.
615 else if (_M_kind == __integer)
617 if (strcmp(__name, "name") == 0)
619 assert(_M_variant._M_integer._M_name);
620 __formatter->_M_print_word(_M_variant._M_integer._M_name);
625 else if (_M_kind == __string)
627 if (strcmp(__name, "name") == 0)
629 assert(_M_variant._M_string._M_name);
630 __formatter->_M_print_word(_M_variant._M_string._M_name);
642 _Error_formatter::_Parameter::
643 _M_print_description(const _Error_formatter* __formatter) const
645 const int __bufsize = 128;
646 char __buf[__bufsize];
648 if (_M_kind == __iterator)
650 __formatter->_M_print_word("iterator ");
651 if (_M_variant._M_iterator._M_name)
653 __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
654 _M_variant._M_iterator._M_name);
655 __formatter->_M_print_word(__buf);
658 __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
659 _M_variant._M_iterator._M_address);
660 __formatter->_M_print_word(__buf);
661 if (_M_variant._M_iterator._M_type)
663 __formatter->_M_print_word("type = ");
664 _M_print_field(__formatter, "type");
666 if (_M_variant._M_iterator._M_constness != __unknown_constness)
668 __formatter->_M_print_word(" (");
669 _M_print_field(__formatter, "constness");
670 __formatter->_M_print_word(" iterator)");
672 __formatter->_M_print_word(";\n");
675 if (_M_variant._M_iterator._M_state != __unknown_state)
677 __formatter->_M_print_word(" state = ");
678 _M_print_field(__formatter, "state");
679 __formatter->_M_print_word(";\n");
682 if (_M_variant._M_iterator._M_sequence)
684 __formatter->_M_print_word(" references sequence ");
685 if (_M_variant._M_iterator._M_seq_type)
687 __formatter->_M_print_word("with type `");
688 _M_print_field(__formatter, "seq_type");
689 __formatter->_M_print_word("' ");
692 __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n",
693 _M_variant._M_sequence._M_address);
694 __formatter->_M_print_word(__buf);
696 __formatter->_M_print_word("}\n");
698 else if (_M_kind == __sequence)
700 __formatter->_M_print_word("sequence ");
701 if (_M_variant._M_sequence._M_name)
703 __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ",
704 _M_variant._M_sequence._M_name);
705 __formatter->_M_print_word(__buf);
708 __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n",
709 _M_variant._M_sequence._M_address);
710 __formatter->_M_print_word(__buf);
712 if (_M_variant._M_sequence._M_type)
714 __formatter->_M_print_word(" type = ");
715 _M_print_field(__formatter, "type");
716 __formatter->_M_print_word(";\n");
718 __formatter->_M_print_word("}\n");
722 const _Error_formatter&
723 _Error_formatter::_M_message(_Debug_msg_id __id) const throw ()
724 { return this->_M_message(_S_debug_messages[__id]); }
727 _Error_formatter::_M_error() const
729 const int __bufsize = 128;
730 char __buf[__bufsize];
732 // Emit file & line number information
737 _M_format_word(__buf, __bufsize, "%s:", _M_file);
738 _M_print_word(__buf);
739 _M_column += strlen(__buf);
744 _M_format_word(__buf, __bufsize, "%u:", _M_line);
745 _M_print_word(__buf);
746 _M_column += strlen(__buf);
751 _M_print_word("error: ");
753 // Print the error message
755 _M_print_string(_M_text);
756 _M_print_word(".\n");
758 // Emit descriptions of the objects involved in the operation
760 bool __has_noninteger_parameters = false;
761 for (unsigned int __i = 0; __i < _M_num_parameters; ++__i)
763 if (_M_parameters[__i]._M_kind == _Parameter::__iterator
764 || _M_parameters[__i]._M_kind == _Parameter::__sequence)
766 if (!__has_noninteger_parameters)
768 _M_first_line = true;
769 _M_print_word("\nObjects involved in the operation:\n");
770 __has_noninteger_parameters = true;
772 _M_parameters[__i]._M_print_description(this);
779 template<typename _Tp>
781 _Error_formatter::_M_format_word(char* __buf,
782 int __n __attribute__ ((__unused__)),
783 const char* __fmt, _Tp __s) const throw ()
785 #ifdef _GLIBCXX_USE_C99
786 std::snprintf(__buf, __n, __fmt, __s);
788 std::sprintf(__buf, __fmt, __s);
794 _Error_formatter::_M_print_word(const char* __word) const
798 fprintf(stderr, "%s", __word);
802 size_t __length = strlen(__word);
806 if ((_M_column + __length < _M_max_length)
807 || (__length >= _M_max_length && _M_column == 1))
809 // If this isn't the first line, indent
810 if (_M_column == 1 && !_M_first_line)
812 char __spacing[_M_indent + 1];
813 for (int i = 0; i < _M_indent; ++i)
815 __spacing[_M_indent] = '\0';
816 fprintf(stderr, "%s", __spacing);
817 _M_column += _M_indent;
820 fprintf(stderr, "%s", __word);
821 _M_column += __length;
823 if (__word[__length - 1] == '\n')
825 _M_first_line = false;
833 _M_print_word(__word);
839 _M_print_string(const char* __string) const
841 const char* __start = __string;
842 const char* __finish = __start;
843 const int __bufsize = 128;
844 char __buf[__bufsize];
850 // [__start, __finish) denotes the next word
852 while (isalnum(*__finish))
854 if (__start == __finish)
856 if (isspace(*__finish))
859 const ptrdiff_t __len = __finish - __start;
860 assert(__len < __bufsize);
861 memcpy(__buf, __start, __len);
863 _M_print_word(__buf);
866 // Skip extra whitespace
867 while (*__start == ' ')
882 // Get the parameter number
883 assert(*__start >= '1' && *__start <= '9');
884 size_t __param = *__start - '0';
886 assert(__param < _M_num_parameters);
888 // '.' separates the parameter number from the field
889 // name, if there is one.
893 assert(*__start == ';');
896 if (_M_parameters[__param]._M_kind == _Parameter::__integer)
898 _M_format_word(__buf, __bufsize, "%ld",
899 _M_parameters[__param]._M_variant._M_integer._M_value);
900 _M_print_word(__buf);
902 else if (_M_parameters[__param]._M_kind == _Parameter::__string)
903 _M_print_string(_M_parameters[__param]._M_variant._M_string._M_value);
907 // Extract the field name we want
908 enum { __max_field_len = 16 };
909 char __field[__max_field_len];
912 while (*__start != ';')
915 assert(__field_idx < __max_field_len-1);
916 __field[__field_idx++] = *__start++;
919 __field[__field_idx] = 0;
921 _M_parameters[__param]._M_print_field(this, __field);
926 _Error_formatter::_M_get_max_length() const throw ()
928 const char* __nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH");
932 const unsigned long __ret = std::strtoul(__nptr, &__endptr, 0);
933 if (*__nptr != '\0' && *__endptr == '\0')
934 _M_max_length = __ret;
941 _Error_formatter::_M_format_word(char*, int, const char*,
946 _Error_formatter::_M_format_word(char*, int, const char*, long) const;
950 _Error_formatter::_M_format_word(char*, int, const char*,
955 _Error_formatter::_M_format_word(char*, int, const char*,
957 } // namespace __gnu_debug