1 // Debugging mode support code -*- C++ -*- 2 3 // Copyright (C) 2003-2019 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 #include <bits/move.h> 26 #include <bits/stl_iterator_base_types.h> 27 28 #include <debug/formatter.h> 29 #include <debug/safe_base.h> 30 #include <debug/safe_unordered_base.h> 31 #include <debug/safe_iterator.h> 32 #include <debug/safe_local_iterator.h> 33 #include <debug/vector> 34 35 #include <cassert> 36 #include <cstdio> 37 #include <cctype> // for std::isspace 38 39 #include <algorithm> // for std::min 40 41 #include <cxxabi.h> // for __cxa_demangle 42 43 // libstdc++/85768 44 #if 0 // defined _GLIBCXX_HAVE_EXECINFO_H 45 # include <execinfo.h> // for backtrace 46 #endif 47 48 #include "mutex_pool.h" 49 50 using namespace std; 51 52 namespace 53 { 54 /** Returns different instances of __mutex depending on the passed address 55 * in order to limit contention without breaking current library binary 56 * compatibility. */ 57 __gnu_cxx::__mutex& get_safe_base_mutex(void * address)58 get_safe_base_mutex(void* address) 59 { 60 // Use arbitrarily __gnu_debug::vector<int> as the container giving 61 // alignment of debug containers. 62 const auto alignbits = __builtin_ctz(alignof(__gnu_debug::vector<int>)); 63 const unsigned char index 64 = (reinterpret_cast<std::size_t>(address) >> alignbits) 65 & __gnu_internal::mask; 66 return __gnu_internal::get_mutex(index); 67 } 68 69 #pragma GCC diagnostic push 70 // Suppress -Wabi=2 warnings due to PR c++/51322 mangling change 71 #pragma GCC diagnostic warning "-Wabi=6" 72 73 void swap_its(__gnu_debug::_Safe_sequence_base & __lhs,__gnu_debug::_Safe_iterator_base * & __lhs_its,__gnu_debug::_Safe_sequence_base & __rhs,__gnu_debug::_Safe_iterator_base * & __rhs_its)74 swap_its(__gnu_debug::_Safe_sequence_base& __lhs, 75 __gnu_debug::_Safe_iterator_base*& __lhs_its, 76 __gnu_debug::_Safe_sequence_base& __rhs, 77 __gnu_debug::_Safe_iterator_base*& __rhs_its) 78 { 79 swap(__lhs_its, __rhs_its); 80 __gnu_debug::_Safe_iterator_base* __iter; 81 for (__iter = __rhs_its; __iter; __iter = __iter->_M_next) 82 __iter->_M_sequence = &__rhs; 83 for (__iter = __lhs_its; __iter; __iter = __iter->_M_next) 84 __iter->_M_sequence = &__lhs; 85 } 86 87 void swap_seq_single(__gnu_debug::_Safe_sequence_base & __lhs,__gnu_debug::_Safe_sequence_base & __rhs)88 swap_seq_single(__gnu_debug::_Safe_sequence_base& __lhs, 89 __gnu_debug::_Safe_sequence_base& __rhs) 90 { 91 swap(__lhs._M_version, __rhs._M_version); 92 swap_its(__lhs, __lhs._M_iterators, 93 __rhs, __rhs._M_iterators); 94 swap_its(__lhs, __lhs._M_const_iterators, 95 __rhs, __rhs._M_const_iterators); 96 } 97 #pragma GCC diagnostic pop 98 99 template<typename _Action> 100 void lock_and_run(__gnu_cxx::__mutex & lhs_mutex,__gnu_cxx::__mutex & rhs_mutex,_Action action)101 lock_and_run(__gnu_cxx::__mutex& lhs_mutex, __gnu_cxx::__mutex& rhs_mutex, 102 _Action action) 103 { 104 // We need to lock both sequences to run action. 105 if (&lhs_mutex == &rhs_mutex) 106 { 107 __gnu_cxx::__scoped_lock sentry(lhs_mutex); 108 action(); 109 } 110 else 111 { 112 __gnu_cxx::__scoped_lock sentry1(&lhs_mutex < &rhs_mutex 113 ? lhs_mutex : rhs_mutex); 114 __gnu_cxx::__scoped_lock sentry2(&lhs_mutex < &rhs_mutex 115 ? rhs_mutex : lhs_mutex); 116 action(); 117 } 118 } 119 120 void swap_seq(__gnu_cxx::__mutex & lhs_mutex,__gnu_debug::_Safe_sequence_base & lhs,__gnu_cxx::__mutex & rhs_mutex,__gnu_debug::_Safe_sequence_base & rhs)121 swap_seq(__gnu_cxx::__mutex& lhs_mutex, 122 __gnu_debug::_Safe_sequence_base& lhs, 123 __gnu_cxx::__mutex& rhs_mutex, 124 __gnu_debug::_Safe_sequence_base& rhs) 125 { 126 lock_and_run(lhs_mutex, rhs_mutex, 127 [&lhs, &rhs]() { swap_seq_single(lhs, rhs); }); 128 } 129 130 void swap_ucont_single(__gnu_debug::_Safe_unordered_container_base & __lhs,__gnu_debug::_Safe_unordered_container_base & __rhs)131 swap_ucont_single(__gnu_debug::_Safe_unordered_container_base& __lhs, 132 __gnu_debug::_Safe_unordered_container_base& __rhs) 133 { 134 swap_seq_single(__lhs, __rhs); 135 swap_its(__lhs, __lhs._M_local_iterators, 136 __rhs, __rhs._M_local_iterators); 137 swap_its(__lhs, __lhs._M_const_local_iterators, 138 __rhs, __rhs._M_const_local_iterators); 139 } 140 141 void swap_ucont(__gnu_cxx::__mutex & lhs_mutex,__gnu_debug::_Safe_unordered_container_base & lhs,__gnu_cxx::__mutex & rhs_mutex,__gnu_debug::_Safe_unordered_container_base & rhs)142 swap_ucont(__gnu_cxx::__mutex& lhs_mutex, 143 __gnu_debug::_Safe_unordered_container_base& lhs, 144 __gnu_cxx::__mutex& rhs_mutex, 145 __gnu_debug::_Safe_unordered_container_base& rhs) 146 { 147 lock_and_run(lhs_mutex, rhs_mutex, 148 [&lhs, &rhs]() { swap_ucont_single(lhs, rhs); }); 149 } 150 151 void detach_all(__gnu_debug::_Safe_iterator_base * __iter)152 detach_all(__gnu_debug::_Safe_iterator_base* __iter) 153 { 154 for (; __iter;) 155 { 156 __gnu_debug::_Safe_iterator_base* __old = __iter; 157 __iter = __iter->_M_next; 158 __old->_M_reset(); 159 } 160 } 161 } // anonymous namespace 162 163 namespace __gnu_debug 164 { 165 const char* const _S_debug_messages[] = 166 { 167 // General Checks 168 "function requires a valid iterator range [%1.name;, %2.name;)", 169 "attempt to insert into container with a singular iterator", 170 "attempt to insert into container with an iterator" 171 " from a different container", 172 "attempt to erase from container with a %2.state; iterator", 173 "attempt to erase from container with an iterator" 174 " from a different container", 175 "attempt to subscript container with out-of-bounds index %2;," 176 " but container only holds %3; elements", 177 "attempt to access an element in an empty container", 178 "elements in iterator range [%1.name;, %2.name;)" 179 " are not partitioned by the value %3;", 180 "elements in iterator range [%1.name;, %2.name;)" 181 " are not partitioned by the predicate %3; and value %4;", 182 "elements in iterator range [%1.name;, %2.name;) are not sorted", 183 "elements in iterator range [%1.name;, %2.name;)" 184 " are not sorted according to the predicate %3;", 185 "elements in iterator range [%1.name;, %2.name;) do not form a heap", 186 "elements in iterator range [%1.name;, %2.name;)" 187 " do not form a heap with respect to the predicate %3;", 188 // std::bitset checks 189 "attempt to write through a singular bitset reference", 190 "attempt to read from a singular bitset reference", 191 "attempt to flip a singular bitset reference", 192 // std::list checks 193 "attempt to splice a list into itself", 194 "attempt to splice lists with unequal allocators", 195 "attempt to splice elements referenced by a %1.state; iterator", 196 "attempt to splice an iterator from a different container", 197 "splice destination %1.name;" 198 " occurs within source range [%2.name;, %3.name;)", 199 // iterator checks 200 "attempt to initialize an iterator that will immediately become singular", 201 "attempt to copy-construct an iterator from a singular iterator", 202 "attempt to construct a constant iterator" 203 " from a singular mutable iterator", 204 "attempt to copy from a singular iterator", 205 "attempt to dereference a %1.state; iterator", 206 "attempt to increment a %1.state; iterator", 207 "attempt to decrement a %1.state; iterator", 208 "attempt to subscript a %1.state; iterator %2; step from" 209 " its current position, which falls outside its dereferenceable range", 210 "attempt to advance a %1.state; iterator %2; steps," 211 " which falls outside its valid range", 212 "attempt to retreat a %1.state; iterator %2; steps," 213 " which falls outside its valid range", 214 "attempt to compare a %1.state; iterator to a %2.state; iterator", 215 "attempt to compare iterators from different sequences", 216 "attempt to order a %1.state; iterator to a %2.state; iterator", 217 "attempt to order iterators from different sequences", 218 "attempt to compute the difference between a %1.state;" 219 " iterator to a %2.state; iterator", 220 "attempt to compute the different between two iterators" 221 " from different sequences", 222 // istream_iterator 223 "attempt to dereference an end-of-stream istream_iterator", 224 "attempt to increment an end-of-stream istream_iterator", 225 // ostream_iterator 226 "attempt to output via an ostream_iterator with no associated stream", 227 // istreambuf_iterator 228 "attempt to dereference an end-of-stream istreambuf_iterator" 229 " (this is a GNU extension)", 230 "attempt to increment an end-of-stream istreambuf_iterator", 231 // std::forward_list 232 "attempt to insert into container after an end iterator", 233 "attempt to erase from container after a %2.state; iterator not followed" 234 " by a dereferenceable one", 235 "function requires a valid iterator range (%2.name;, %3.name;)" 236 ", \"%2.name;\" shall be before and not equal to \"%3.name;\"", 237 // std::unordered_container::local_iterator 238 "attempt to compare local iterators from different unordered container" 239 " buckets", 240 "function requires a non-empty iterator range [%1.name;, %2.name;)", 241 "attempt to self move assign", 242 "attempt to access container with out-of-bounds bucket index %2;," 243 " container only holds %3; buckets", 244 "load factor shall be positive", 245 "allocators must be equal", 246 "attempt to insert with an iterator range [%1.name;, %2.name;) from this" 247 " container", 248 "comparison doesn't meet irreflexive requirements, assert(!(a < a))" 249 }; 250 251 void 252 _Safe_sequence_base:: _M_detach_all()253 _M_detach_all() 254 { 255 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 256 detach_all(_M_iterators); 257 _M_iterators = 0; 258 259 detach_all(_M_const_iterators); 260 _M_const_iterators = 0; 261 } 262 263 void 264 _Safe_sequence_base:: _M_detach_singular()265 _M_detach_singular() 266 { 267 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 268 for (_Safe_iterator_base* __iter = _M_iterators; __iter;) 269 { 270 _Safe_iterator_base* __old = __iter; 271 __iter = __iter->_M_next; 272 if (__old->_M_singular()) 273 __old->_M_detach_single(); 274 } 275 276 for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) 277 { 278 _Safe_iterator_base* __old = __iter2; 279 __iter2 = __iter2->_M_next; 280 if (__old->_M_singular()) 281 __old->_M_detach_single(); 282 } 283 } 284 285 void 286 _Safe_sequence_base:: _M_revalidate_singular()287 _M_revalidate_singular() 288 { 289 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 290 for (_Safe_iterator_base* __iter = _M_iterators; __iter; 291 __iter = __iter->_M_next) 292 __iter->_M_version = _M_version; 293 294 for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; 295 __iter2 = __iter2->_M_next) 296 __iter2->_M_version = _M_version; 297 } 298 299 void 300 _Safe_sequence_base:: _M_swap(_Safe_sequence_base & __x)301 _M_swap(_Safe_sequence_base& __x) noexcept 302 { swap_seq(_M_get_mutex(), *this, __x._M_get_mutex(), __x); } 303 304 __gnu_cxx::__mutex& 305 _Safe_sequence_base:: _M_get_mutex()306 _M_get_mutex() throw () 307 { return get_safe_base_mutex(this); } 308 309 void 310 _Safe_sequence_base:: _M_attach(_Safe_iterator_base * __it,bool __constant)311 _M_attach(_Safe_iterator_base* __it, bool __constant) 312 { 313 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 314 _M_attach_single(__it, __constant); 315 } 316 317 void 318 _Safe_sequence_base:: _M_attach_single(_Safe_iterator_base * __it,bool __constant)319 _M_attach_single(_Safe_iterator_base* __it, bool __constant) throw () 320 { 321 _Safe_iterator_base*& __its = 322 __constant ? _M_const_iterators : _M_iterators; 323 __it->_M_next = __its; 324 if (__it->_M_next) 325 __it->_M_next->_M_prior = __it; 326 __its = __it; 327 } 328 329 void 330 _Safe_sequence_base:: _M_detach(_Safe_iterator_base * __it)331 _M_detach(_Safe_iterator_base* __it) 332 { 333 // Remove __it from this sequence's list 334 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 335 _M_detach_single(__it); 336 } 337 338 void 339 _Safe_sequence_base:: _M_detach_single(_Safe_iterator_base * __it)340 _M_detach_single(_Safe_iterator_base* __it) throw () 341 { 342 // Remove __it from this sequence's list 343 __it->_M_unlink(); 344 if (_M_const_iterators == __it) 345 _M_const_iterators = __it->_M_next; 346 if (_M_iterators == __it) 347 _M_iterators = __it->_M_next; 348 } 349 350 void 351 _Safe_iterator_base:: _M_attach(_Safe_sequence_base * __seq,bool __constant)352 _M_attach(_Safe_sequence_base* __seq, bool __constant) 353 { 354 _M_detach(); 355 356 // Attach to the new sequence (if there is one) 357 if (__seq) 358 { 359 _M_sequence = __seq; 360 _M_version = _M_sequence->_M_version; 361 _M_sequence->_M_attach(this, __constant); 362 } 363 } 364 365 void 366 _Safe_iterator_base:: _M_attach_single(_Safe_sequence_base * __seq,bool __constant)367 _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw () 368 { 369 _M_detach_single(); 370 371 // Attach to the new sequence (if there is one) 372 if (__seq) 373 { 374 _M_sequence = __seq; 375 _M_version = _M_sequence->_M_version; 376 _M_sequence->_M_attach_single(this, __constant); 377 } 378 } 379 380 void 381 _Safe_iterator_base:: _M_detach()382 _M_detach() 383 { 384 // This function can run concurrently with the sequence destructor, 385 // so there is a TOCTTOU race here: the sequence could be destroyed 386 // after we check that _M_sequence is not null. Use the pointer value 387 // to acquire the mutex (rather than via _M_sequence->_M_get_mutex()). 388 // If the sequence destructor runs between loading the pointer and 389 // locking the mutex, it will detach this iterator and set _M_sequence 390 // to null, and then _M_detach_single() will do nothing. 391 if (auto seq = __atomic_load_n(&_M_sequence, __ATOMIC_ACQUIRE)) 392 { 393 __gnu_cxx::__scoped_lock sentry(get_safe_base_mutex(seq)); 394 _M_detach_single(); 395 } 396 } 397 398 void 399 _Safe_iterator_base:: _M_detach_single()400 _M_detach_single() throw () 401 { 402 if (_M_sequence) 403 { 404 _M_sequence->_M_detach_single(this); 405 _M_reset(); 406 } 407 } 408 409 void 410 _Safe_iterator_base:: _M_reset()411 _M_reset() throw () 412 { 413 __atomic_store_n(&_M_sequence, (_Safe_sequence_base*)0, __ATOMIC_RELEASE); 414 _M_version = 0; 415 _M_prior = 0; 416 _M_next = 0; 417 } 418 419 bool 420 _Safe_iterator_base:: _M_singular() const421 _M_singular() const throw () 422 { return !_M_sequence || _M_version != _M_sequence->_M_version; } 423 424 bool 425 _Safe_iterator_base:: _M_can_compare(const _Safe_iterator_base & __x) const426 _M_can_compare(const _Safe_iterator_base& __x) const throw () 427 { 428 return (!_M_singular() 429 && !__x._M_singular() && _M_sequence == __x._M_sequence); 430 } 431 432 __gnu_cxx::__mutex& 433 _Safe_iterator_base:: _M_get_mutex()434 _M_get_mutex() throw () 435 { return _M_sequence->_M_get_mutex(); } 436 437 _Safe_unordered_container_base* 438 _Safe_local_iterator_base:: _M_get_container() const439 _M_get_container() const noexcept 440 { return static_cast<_Safe_unordered_container_base*>(_M_sequence); } 441 442 void 443 _Safe_local_iterator_base:: _M_attach(_Safe_sequence_base * __cont,bool __constant)444 _M_attach(_Safe_sequence_base* __cont, bool __constant) 445 { 446 _M_detach(); 447 448 // Attach to the new container (if there is one) 449 if (__cont) 450 { 451 _M_sequence = __cont; 452 _M_version = _M_sequence->_M_version; 453 _M_get_container()->_M_attach_local(this, __constant); 454 } 455 } 456 457 void 458 _Safe_local_iterator_base:: _M_attach_single(_Safe_sequence_base * __cont,bool __constant)459 _M_attach_single(_Safe_sequence_base* __cont, bool __constant) throw () 460 { 461 _M_detach_single(); 462 463 // Attach to the new container (if there is one) 464 if (__cont) 465 { 466 _M_sequence = __cont; 467 _M_version = _M_sequence->_M_version; 468 _M_get_container()->_M_attach_local_single(this, __constant); 469 } 470 } 471 472 void 473 _Safe_local_iterator_base:: _M_detach()474 _M_detach() 475 { 476 if (auto seq = __atomic_load_n(&_M_sequence, __ATOMIC_ACQUIRE)) 477 { 478 __gnu_cxx::__scoped_lock sentry(get_safe_base_mutex(seq)); 479 _M_detach_single(); 480 } 481 } 482 483 void 484 _Safe_local_iterator_base:: _M_detach_single()485 _M_detach_single() throw () 486 { 487 if (_M_sequence) 488 { 489 _M_get_container()->_M_detach_local_single(this); 490 _M_reset(); 491 } 492 } 493 494 void 495 _Safe_unordered_container_base:: _M_detach_all()496 _M_detach_all() 497 { 498 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 499 detach_all(_M_iterators); 500 _M_iterators = 0; 501 502 detach_all(_M_const_iterators); 503 _M_const_iterators = 0; 504 505 detach_all(_M_local_iterators); 506 _M_local_iterators = 0; 507 508 detach_all(_M_const_local_iterators); 509 _M_const_local_iterators = 0; 510 } 511 512 void 513 _Safe_unordered_container_base:: _M_swap(_Safe_unordered_container_base & __x)514 _M_swap(_Safe_unordered_container_base& __x) noexcept 515 { swap_ucont(_M_get_mutex(), *this, __x._M_get_mutex(), __x); } 516 517 void 518 _Safe_unordered_container_base:: _M_attach_local(_Safe_iterator_base * __it,bool __constant)519 _M_attach_local(_Safe_iterator_base* __it, bool __constant) 520 { 521 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 522 _M_attach_local_single(__it, __constant); 523 } 524 525 void 526 _Safe_unordered_container_base:: _M_attach_local_single(_Safe_iterator_base * __it,bool __constant)527 _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw () 528 { 529 _Safe_iterator_base*& __its = 530 __constant ? _M_const_local_iterators : _M_local_iterators; 531 __it->_M_next = __its; 532 if (__it->_M_next) 533 __it->_M_next->_M_prior = __it; 534 __its = __it; 535 } 536 537 void 538 _Safe_unordered_container_base:: _M_detach_local(_Safe_iterator_base * __it)539 _M_detach_local(_Safe_iterator_base* __it) 540 { 541 // Remove __it from this container's list 542 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 543 _M_detach_local_single(__it); 544 } 545 546 void 547 _Safe_unordered_container_base:: _M_detach_local_single(_Safe_iterator_base * __it)548 _M_detach_local_single(_Safe_iterator_base* __it) throw () 549 { 550 // Remove __it from this container's list 551 __it->_M_unlink(); 552 if (_M_const_local_iterators == __it) 553 _M_const_local_iterators = __it->_M_next; 554 if (_M_local_iterators == __it) 555 _M_local_iterators = __it->_M_next; 556 } 557 } 558 559 namespace 560 { 561 using _Error_formatter = __gnu_debug::_Error_formatter; 562 using _Parameter = __gnu_debug::_Error_formatter::_Parameter; 563 564 void get_max_length(std::size_t & max_length)565 get_max_length(std::size_t& max_length) 566 { 567 const char* nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH"); 568 if (nptr) 569 { 570 char* endptr; 571 const unsigned long ret = std::strtoul(nptr, &endptr, 0); 572 if (*nptr != '\0' && *endptr == '\0') 573 max_length = ret; 574 } 575 } 576 577 struct PrintContext 578 { PrintContext__anone1e30a4d0411::PrintContext579 PrintContext() 580 : _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) 581 { get_max_length(_M_max_length); } 582 583 std::size_t _M_max_length; 584 enum { _M_indent = 4 } ; 585 std::size_t _M_column; 586 bool _M_first_line; 587 bool _M_wordwrap; 588 }; 589 590 template<size_t Length> 591 void print_literal(PrintContext & ctx,const char (& word)[Length])592 print_literal(PrintContext& ctx, const char(&word)[Length]) 593 { print_word(ctx, word, Length - 1); } 594 595 void print_word(PrintContext & ctx,const char * word,std::ptrdiff_t count=-1)596 print_word(PrintContext& ctx, const char* word, 597 std::ptrdiff_t count = -1) 598 { 599 size_t length = count >= 0 ? count : __builtin_strlen(word); 600 if (length == 0) 601 return; 602 603 // Consider first '\n' at begining cause it impacts column. 604 if (word[0] == '\n') 605 { 606 fprintf(stderr, "\n"); 607 ctx._M_column = 1; 608 ++word; 609 --length; 610 611 if (length == 0) 612 return; 613 } 614 615 size_t visual_length 616 = isspace(word[length - 1]) ? length - 1 : length; 617 if (visual_length == 0 618 || !ctx._M_wordwrap 619 || (ctx._M_column + visual_length < ctx._M_max_length) 620 || (visual_length >= ctx._M_max_length && ctx._M_column == 1)) 621 { 622 // If this isn't the first line, indent 623 if (ctx._M_column == 1 && !ctx._M_first_line) 624 { 625 char spacing[ctx._M_indent + 1]; 626 for (int i = 0; i < ctx._M_indent; ++i) 627 spacing[i] = ' '; 628 spacing[ctx._M_indent] = '\0'; 629 fprintf(stderr, "%s", spacing); 630 ctx._M_column += ctx._M_indent; 631 } 632 633 int written = fprintf(stderr, "%s", word); 634 635 if (word[length - 1] == '\n') 636 { 637 ctx._M_first_line = false; 638 ctx._M_column = 1; 639 } 640 else 641 ctx._M_column += written; 642 } 643 else 644 { 645 print_literal(ctx, "\n"); 646 print_word(ctx, word, count); 647 } 648 } 649 650 template<size_t Length> 651 void print_type(PrintContext & ctx,const type_info * info,const char (& unknown_name)[Length])652 print_type(PrintContext& ctx, 653 const type_info* info, 654 const char(&unknown_name)[Length]) 655 { 656 if (!info) 657 print_literal(ctx, unknown_name); 658 else 659 { 660 int status; 661 char* demangled_name = 662 __cxxabiv1::__cxa_demangle(info->name(), NULL, NULL, &status); 663 print_word(ctx, status == 0 ? demangled_name : info->name()); 664 free(demangled_name); 665 } 666 } 667 668 bool print_field(PrintContext & ctx,const char * name,const _Parameter::_Type & type)669 print_field(PrintContext& ctx, 670 const char* name, const _Parameter::_Type& type) 671 { 672 if (__builtin_strcmp(name, "name") == 0) 673 { 674 assert(type._M_name); 675 print_word(ctx, type._M_name); 676 } 677 else if (__builtin_strcmp(name, "type") == 0) 678 print_type(ctx, type._M_type, "<unknown type>"); 679 else 680 return false; 681 682 return true; 683 } 684 685 bool print_field(PrintContext & ctx,const char * name,const _Parameter::_Instance & inst)686 print_field(PrintContext& ctx, 687 const char* name, const _Parameter::_Instance& inst) 688 { 689 const _Parameter::_Type& type = inst; 690 if (print_field(ctx, name, type)) 691 { } 692 else if (__builtin_strcmp(name, "address") == 0) 693 { 694 char buf[64]; 695 int ret = __builtin_sprintf(buf, "%p", inst._M_address); 696 print_word(ctx, buf, ret); 697 } 698 else 699 return false; 700 701 return true; 702 } 703 704 void print_field(PrintContext & ctx,const _Parameter & param,const char * name)705 print_field(PrintContext& ctx, const _Parameter& param, const char* name) 706 { 707 assert(param._M_kind != _Parameter::__unused_param); 708 const int bufsize = 64; 709 char buf[bufsize]; 710 711 const auto& variant = param._M_variant; 712 switch (param._M_kind) 713 { 714 case _Parameter::__iterator: 715 { 716 const auto& iterator = variant._M_iterator; 717 if (print_field(ctx, name, iterator)) 718 { } 719 else if (__builtin_strcmp(name, "constness") == 0) 720 { 721 static const char* 722 constness_names[_Error_formatter::__last_constness] = 723 { 724 "<unknown>", 725 "constant", 726 "mutable" 727 }; 728 print_word(ctx, constness_names[iterator._M_constness]); 729 } 730 else if (__builtin_strcmp(name, "state") == 0) 731 { 732 static const char* 733 state_names[_Error_formatter::__last_state] = 734 { 735 "<unknown>", 736 "singular", 737 "dereferenceable (start-of-sequence)", 738 "dereferenceable", 739 "past-the-end", 740 "before-begin", 741 "dereferenceable (start-of-reverse-sequence)", 742 "dereferenceable (reverse)", 743 "past-the-reverse-end" 744 }; 745 print_word(ctx, state_names[iterator._M_state]); 746 } 747 else if (__builtin_strcmp(name, "sequence") == 0) 748 { 749 assert(iterator._M_sequence); 750 int written = __builtin_sprintf(buf, "%p", iterator._M_sequence); 751 print_word(ctx, buf, written); 752 } 753 else if (__builtin_strcmp(name, "seq_type") == 0) 754 print_type(ctx, iterator._M_seq_type, "<unknown seq_type>"); 755 else 756 assert(false); 757 } 758 break; 759 760 case _Parameter::__sequence: 761 if (!print_field(ctx, name, variant._M_sequence)) 762 assert(false); 763 break; 764 765 case _Parameter::__integer: 766 if (__builtin_strcmp(name, "name") == 0) 767 { 768 assert(variant._M_integer._M_name); 769 print_word(ctx, variant._M_integer._M_name); 770 } 771 else 772 assert(false); 773 break; 774 775 case _Parameter::__string: 776 if (__builtin_strcmp(name, "name") == 0) 777 { 778 assert(variant._M_string._M_name); 779 print_word(ctx, variant._M_string._M_name); 780 } 781 else 782 assert(false); 783 break; 784 785 case _Parameter::__instance: 786 if (!print_field(ctx, name, variant._M_instance)) 787 assert(false); 788 break; 789 790 case _Parameter::__iterator_value_type: 791 if (!print_field(ctx, name, variant._M_iterator_value_type)) 792 assert(false); 793 break; 794 795 default: 796 assert(false); 797 break; 798 } 799 } 800 801 void print_description(PrintContext & ctx,const _Parameter::_Type & type)802 print_description(PrintContext& ctx, const _Parameter::_Type& type) 803 { 804 if (type._M_name) 805 { 806 print_literal(ctx, "\""); 807 print_word(ctx, type._M_name); 808 print_literal(ctx, "\""); 809 } 810 811 print_literal(ctx, " {\n"); 812 813 if (type._M_type) 814 { 815 print_literal(ctx, " type = "); 816 print_type(ctx, type._M_type, "<unknown type>"); 817 print_literal(ctx, ";\n"); 818 } 819 } 820 821 void print_description(PrintContext & ctx,const _Parameter::_Instance & inst)822 print_description(PrintContext& ctx, const _Parameter::_Instance& inst) 823 { 824 const int bufsize = 64; 825 char buf[bufsize]; 826 827 if (inst._M_name) 828 { 829 print_literal(ctx, "\""); 830 print_word(ctx, inst._M_name); 831 print_literal(ctx, "\" "); 832 } 833 834 int written 835 = __builtin_sprintf(buf, "@ 0x%p {\n", inst._M_address); 836 print_word(ctx, buf, written); 837 838 if (inst._M_type) 839 { 840 print_literal(ctx, " type = "); 841 print_type(ctx, inst._M_type, "<unknown type>"); 842 } 843 } 844 845 void print_description(PrintContext & ctx,const _Parameter & param)846 print_description(PrintContext& ctx, const _Parameter& param) 847 { 848 const int bufsize = 128; 849 char buf[bufsize]; 850 851 const auto& variant = param._M_variant; 852 switch (param._M_kind) 853 { 854 case _Parameter::__iterator: 855 { 856 const auto& ite = variant._M_iterator; 857 858 print_literal(ctx, "iterator "); 859 print_description(ctx, ite); 860 861 if (ite._M_type) 862 { 863 if (ite._M_constness != _Error_formatter::__unknown_constness) 864 { 865 print_literal(ctx, " ("); 866 print_field(ctx, param, "constness"); 867 print_literal(ctx, " iterator)"); 868 } 869 870 print_literal(ctx, ";\n"); 871 } 872 873 if (ite._M_state != _Error_formatter::__unknown_state) 874 { 875 print_literal(ctx, " state = "); 876 print_field(ctx, param, "state"); 877 print_literal(ctx, ";\n"); 878 } 879 880 if (ite._M_sequence) 881 { 882 print_literal(ctx, " references sequence "); 883 if (ite._M_seq_type) 884 { 885 print_literal(ctx, "with type '"); 886 print_field(ctx, param, "seq_type"); 887 print_literal(ctx, "' "); 888 } 889 890 int written 891 = __builtin_sprintf(buf, "@ 0x%p\n", ite._M_sequence); 892 print_word(ctx, buf, written); 893 } 894 895 print_literal(ctx, "}\n"); 896 } 897 break; 898 899 case _Parameter::__sequence: 900 print_literal(ctx, "sequence "); 901 print_description(ctx, variant._M_sequence); 902 903 if (variant._M_sequence._M_type) 904 print_literal(ctx, ";\n"); 905 906 print_literal(ctx, "}\n"); 907 break; 908 909 case _Parameter::__instance: 910 print_literal(ctx, "instance "); 911 print_description(ctx, variant._M_instance); 912 913 if (variant._M_instance._M_type) 914 print_literal(ctx, ";\n"); 915 916 print_literal(ctx, "}\n"); 917 break; 918 919 case _Parameter::__iterator_value_type: 920 print_literal(ctx, "iterator::value_type "); 921 print_description(ctx, variant._M_iterator_value_type); 922 print_literal(ctx, "}\n"); 923 break; 924 925 default: 926 break; 927 } 928 } 929 930 void print_string(PrintContext & ctx,const char * string,const _Parameter * parameters,std::size_t num_parameters)931 print_string(PrintContext& ctx, const char* string, 932 const _Parameter* parameters, std::size_t num_parameters) 933 { 934 const char* start = string; 935 const int bufsize = 128; 936 char buf[bufsize]; 937 int bufindex = 0; 938 939 while (*start) 940 { 941 if (isspace(*start)) 942 { 943 buf[bufindex++] = *start++; 944 buf[bufindex] = '\0'; 945 print_word(ctx, buf, bufindex); 946 bufindex = 0; 947 continue; 948 } 949 950 if (!num_parameters || *start != '%') 951 { 952 // Normal char or no parameter to look for. 953 buf[bufindex++] = *start++; 954 continue; 955 } 956 957 if (*++start == '%') 958 { 959 // Escaped '%' 960 buf[bufindex++] = *start++; 961 continue; 962 } 963 964 // We are on a parameter property reference, we need to flush buffer 965 // first. 966 if (bufindex != 0) 967 { 968 buf[bufindex] = '\0'; 969 print_word(ctx, buf, bufindex); 970 bufindex = 0; 971 } 972 973 // Get the parameter number 974 assert(*start >= '1' && *start <= '9'); 975 size_t param_index = *start - '0' - 1; 976 assert(param_index < num_parameters); 977 const auto& param = parameters[param_index]; 978 979 // '.' separates the parameter number from the field 980 // name, if there is one. 981 ++start; 982 if (*start != '.') 983 { 984 assert(*start == ';'); 985 ++start; 986 if (param._M_kind == _Parameter::__integer) 987 { 988 int written 989 = __builtin_sprintf(buf, "%ld", 990 param._M_variant._M_integer._M_value); 991 print_word(ctx, buf, written); 992 } 993 else if (param._M_kind == _Parameter::__string) 994 print_string(ctx, param._M_variant._M_string._M_value, 995 parameters, num_parameters); 996 continue; 997 } 998 999 // Extract the field name we want 1000 const int max_field_len = 16; 1001 char field[max_field_len]; 1002 int field_idx = 0; 1003 ++start; 1004 while (*start != ';') 1005 { 1006 assert(*start); 1007 assert(field_idx < max_field_len - 1); 1008 field[field_idx++] = *start++; 1009 } 1010 ++start; 1011 field[field_idx] = '\0'; 1012 1013 print_field(ctx, param, field); 1014 } 1015 1016 // Might need to flush. 1017 if (bufindex) 1018 { 1019 buf[bufindex] = '\0'; 1020 print_word(ctx, buf, bufindex); 1021 } 1022 } 1023 } 1024 1025 namespace __gnu_debug 1026 { 1027 _Error_formatter& _M_message(_Debug_msg_id __id) const1028 _Error_formatter::_M_message(_Debug_msg_id __id) const throw () 1029 { 1030 return const_cast<_Error_formatter*>(this) 1031 ->_M_message(_S_debug_messages[__id]); 1032 } 1033 1034 void _M_error() const1035 _Error_formatter::_M_error() const 1036 { 1037 // Emit file & line number information 1038 bool go_to_next_line = false; 1039 PrintContext ctx; 1040 if (_M_file) 1041 { 1042 print_word(ctx, _M_file); 1043 print_literal(ctx, ":"); 1044 go_to_next_line = true; 1045 } 1046 1047 if (_M_line > 0) 1048 { 1049 char buf[64]; 1050 int written = __builtin_sprintf(buf, "%u:", _M_line); 1051 print_word(ctx, buf, written); 1052 go_to_next_line = true; 1053 } 1054 1055 if (go_to_next_line) 1056 print_literal(ctx, "\n"); 1057 1058 if (ctx._M_max_length) 1059 ctx._M_wordwrap = true; 1060 1061 if (_M_function) 1062 { 1063 print_literal(ctx, "In function:\n"); 1064 print_string(ctx, _M_function, nullptr, 0); 1065 print_literal(ctx, "\n"); 1066 ctx._M_first_line = true; 1067 print_literal(ctx, "\n"); 1068 } 1069 1070 // libstdc++/85768 1071 #if 0 //defined _GLIBCXX_HAVE_EXECINFO_H 1072 { 1073 void* stack[32]; 1074 int nb = backtrace(stack, 32); 1075 1076 // Note that we skip current method symbol. 1077 if (nb > 1) 1078 { 1079 print_literal(ctx, "Backtrace:\n"); 1080 auto symbols = backtrace_symbols(stack, nb); 1081 for (int i = 1; i < nb; ++i) 1082 { 1083 print_word(ctx, symbols[i]); 1084 print_literal(ctx, "\n"); 1085 } 1086 1087 free(symbols); 1088 ctx._M_first_line = true; 1089 print_literal(ctx, "\n"); 1090 } 1091 } 1092 #endif 1093 1094 print_literal(ctx, "Error: "); 1095 1096 // Print the error message 1097 assert(_M_text); 1098 print_string(ctx, _M_text, _M_parameters, _M_num_parameters); 1099 print_literal(ctx, ".\n"); 1100 1101 // Emit descriptions of the objects involved in the operation 1102 ctx._M_first_line = true; 1103 ctx._M_wordwrap = false; 1104 bool has_header = false; 1105 for (unsigned int i = 0; i < _M_num_parameters; ++i) 1106 { 1107 switch (_M_parameters[i]._M_kind) 1108 { 1109 case _Parameter::__iterator: 1110 case _Parameter::__sequence: 1111 case _Parameter::__instance: 1112 case _Parameter::__iterator_value_type: 1113 if (!has_header) 1114 { 1115 print_literal(ctx, "\nObjects involved in the operation:\n"); 1116 has_header = true; 1117 } 1118 print_description(ctx, _M_parameters[i]); 1119 break; 1120 1121 default: 1122 break; 1123 } 1124 } 1125 1126 abort(); 1127 } 1128 1129 #if !_GLIBCXX_INLINE_VERSION 1130 // Deprecated methods kept for backward compatibility. 1131 void _M_print_field(const _Error_formatter *,const char *) const1132 _Error_formatter::_Parameter::_M_print_field( 1133 const _Error_formatter*, const char*) const 1134 { } 1135 1136 void _M_print_description(const _Error_formatter *) const1137 _Error_formatter::_Parameter::_M_print_description(const _Error_formatter*) const 1138 { } 1139 1140 template<typename _Tp> 1141 void _M_format_word(char *,int,const char *,_Tp) const1142 _Error_formatter::_M_format_word(char*, int, const char*, _Tp) 1143 const throw () 1144 { } 1145 1146 void _M_print_word(const char *) const1147 _Error_formatter::_M_print_word(const char*) const 1148 { } 1149 1150 void _M_print_string(const char *) const1151 _Error_formatter::_M_print_string(const char*) const 1152 { } 1153 1154 void _M_get_max_length() const1155 _Error_formatter::_M_get_max_length() const throw () 1156 { } 1157 1158 // Instantiations. 1159 template 1160 void 1161 _Error_formatter::_M_format_word(char*, int, const char*, 1162 const void*) const; 1163 1164 template 1165 void 1166 _Error_formatter::_M_format_word(char*, int, const char*, long) const; 1167 1168 template 1169 void 1170 _Error_formatter::_M_format_word(char*, int, const char*, 1171 std::size_t) const; 1172 1173 template 1174 void 1175 _Error_formatter::_M_format_word(char*, int, const char*, 1176 const char*) const; 1177 #endif 1178 1179 } // namespace __gnu_debug 1180