1 // Debugging mode support code -*- C++ -*- 2 3 // Copyright (C) 2003-2021 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 { return _M_sequence == __x._M_sequence; } 428 429 __gnu_cxx::__mutex& 430 _Safe_iterator_base:: _M_get_mutex()431 _M_get_mutex() throw () 432 { return _M_sequence->_M_get_mutex(); } 433 434 _Safe_unordered_container_base* 435 _Safe_local_iterator_base:: _M_get_container() const436 _M_get_container() const noexcept 437 { return static_cast<_Safe_unordered_container_base*>(_M_sequence); } 438 439 void 440 _Safe_local_iterator_base:: _M_attach(_Safe_sequence_base * __cont,bool __constant)441 _M_attach(_Safe_sequence_base* __cont, bool __constant) 442 { 443 _M_detach(); 444 445 // Attach to the new container (if there is one) 446 if (__cont) 447 { 448 _M_sequence = __cont; 449 _M_version = _M_sequence->_M_version; 450 _M_get_container()->_M_attach_local(this, __constant); 451 } 452 } 453 454 void 455 _Safe_local_iterator_base:: _M_attach_single(_Safe_sequence_base * __cont,bool __constant)456 _M_attach_single(_Safe_sequence_base* __cont, bool __constant) throw () 457 { 458 _M_detach_single(); 459 460 // Attach to the new container (if there is one) 461 if (__cont) 462 { 463 _M_sequence = __cont; 464 _M_version = _M_sequence->_M_version; 465 _M_get_container()->_M_attach_local_single(this, __constant); 466 } 467 } 468 469 void 470 _Safe_local_iterator_base:: _M_detach()471 _M_detach() 472 { 473 if (auto seq = __atomic_load_n(&_M_sequence, __ATOMIC_ACQUIRE)) 474 { 475 __gnu_cxx::__scoped_lock sentry(get_safe_base_mutex(seq)); 476 _M_detach_single(); 477 } 478 } 479 480 void 481 _Safe_local_iterator_base:: _M_detach_single()482 _M_detach_single() throw () 483 { 484 if (_M_sequence) 485 { 486 _M_get_container()->_M_detach_local_single(this); 487 _M_reset(); 488 } 489 } 490 491 void 492 _Safe_unordered_container_base:: _M_detach_all()493 _M_detach_all() 494 { 495 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 496 detach_all(_M_iterators); 497 _M_iterators = 0; 498 499 detach_all(_M_const_iterators); 500 _M_const_iterators = 0; 501 502 detach_all(_M_local_iterators); 503 _M_local_iterators = 0; 504 505 detach_all(_M_const_local_iterators); 506 _M_const_local_iterators = 0; 507 } 508 509 void 510 _Safe_unordered_container_base:: _M_swap(_Safe_unordered_container_base & __x)511 _M_swap(_Safe_unordered_container_base& __x) noexcept 512 { swap_ucont(_M_get_mutex(), *this, __x._M_get_mutex(), __x); } 513 514 void 515 _Safe_unordered_container_base:: _M_attach_local(_Safe_iterator_base * __it,bool __constant)516 _M_attach_local(_Safe_iterator_base* __it, bool __constant) 517 { 518 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 519 _M_attach_local_single(__it, __constant); 520 } 521 522 void 523 _Safe_unordered_container_base:: _M_attach_local_single(_Safe_iterator_base * __it,bool __constant)524 _M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw () 525 { 526 _Safe_iterator_base*& __its = 527 __constant ? _M_const_local_iterators : _M_local_iterators; 528 __it->_M_next = __its; 529 if (__it->_M_next) 530 __it->_M_next->_M_prior = __it; 531 __its = __it; 532 } 533 534 void 535 _Safe_unordered_container_base:: _M_detach_local(_Safe_iterator_base * __it)536 _M_detach_local(_Safe_iterator_base* __it) 537 { 538 // Remove __it from this container's list 539 __gnu_cxx::__scoped_lock sentry(_M_get_mutex()); 540 _M_detach_local_single(__it); 541 } 542 543 void 544 _Safe_unordered_container_base:: _M_detach_local_single(_Safe_iterator_base * __it)545 _M_detach_local_single(_Safe_iterator_base* __it) throw () 546 { 547 // Remove __it from this container's list 548 __it->_M_unlink(); 549 if (_M_const_local_iterators == __it) 550 _M_const_local_iterators = __it->_M_next; 551 if (_M_local_iterators == __it) 552 _M_local_iterators = __it->_M_next; 553 } 554 } 555 556 namespace 557 { 558 using _Error_formatter = __gnu_debug::_Error_formatter; 559 using _Parameter = __gnu_debug::_Error_formatter::_Parameter; 560 561 void get_max_length(std::size_t & max_length)562 get_max_length(std::size_t& max_length) 563 { 564 const char* nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH"); 565 if (nptr) 566 { 567 char* endptr; 568 const unsigned long ret = std::strtoul(nptr, &endptr, 0); 569 if (*nptr != '\0' && *endptr == '\0') 570 max_length = ret; 571 } 572 } 573 574 struct PrintContext 575 { PrintContext__anon976c37160411::PrintContext576 PrintContext() 577 : _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) 578 { get_max_length(_M_max_length); } 579 580 std::size_t _M_max_length; 581 enum { _M_indent = 4 } ; 582 std::size_t _M_column; 583 bool _M_first_line; 584 bool _M_wordwrap; 585 }; 586 587 template<size_t Length> 588 void print_literal(PrintContext & ctx,const char (& word)[Length])589 print_literal(PrintContext& ctx, const char(&word)[Length]) 590 { print_word(ctx, word, Length - 1); } 591 592 void print_word(PrintContext & ctx,const char * word,std::ptrdiff_t count=-1)593 print_word(PrintContext& ctx, const char* word, 594 std::ptrdiff_t count = -1) 595 { 596 size_t length = count >= 0 ? count : __builtin_strlen(word); 597 if (length == 0) 598 return; 599 600 // Consider first '\n' at begining cause it impacts column. 601 if (word[0] == '\n') 602 { 603 fprintf(stderr, "\n"); 604 ctx._M_column = 1; 605 ++word; 606 --length; 607 608 if (length == 0) 609 return; 610 } 611 612 size_t visual_length 613 = isspace(word[length - 1]) ? length - 1 : length; 614 if (visual_length == 0 615 || !ctx._M_wordwrap 616 || (ctx._M_column + visual_length < ctx._M_max_length) 617 || (visual_length >= ctx._M_max_length && ctx._M_column == 1)) 618 { 619 // If this isn't the first line, indent 620 if (ctx._M_column == 1 && !ctx._M_first_line) 621 { 622 char spacing[ctx._M_indent + 1]; 623 for (int i = 0; i < ctx._M_indent; ++i) 624 spacing[i] = ' '; 625 spacing[ctx._M_indent] = '\0'; 626 fprintf(stderr, "%s", spacing); 627 ctx._M_column += ctx._M_indent; 628 } 629 630 int written = fprintf(stderr, "%s", word); 631 632 if (word[length - 1] == '\n') 633 { 634 ctx._M_first_line = false; 635 ctx._M_column = 1; 636 } 637 else 638 ctx._M_column += written; 639 } 640 else 641 { 642 print_literal(ctx, "\n"); 643 print_word(ctx, word, count); 644 } 645 } 646 647 template<size_t Length> 648 void print_type(PrintContext & ctx,const type_info * info,const char (& unknown_name)[Length])649 print_type(PrintContext& ctx, 650 const type_info* info, 651 const char(&unknown_name)[Length]) 652 { 653 if (!info) 654 print_literal(ctx, unknown_name); 655 else 656 { 657 int status; 658 char* demangled_name = 659 __cxxabiv1::__cxa_demangle(info->name(), NULL, NULL, &status); 660 print_word(ctx, status == 0 ? demangled_name : info->name()); 661 free(demangled_name); 662 } 663 } 664 665 bool print_field(PrintContext & ctx,const char * name,const _Parameter::_Type & type)666 print_field(PrintContext& ctx, 667 const char* name, const _Parameter::_Type& type) 668 { 669 if (__builtin_strcmp(name, "name") == 0) 670 { 671 assert(type._M_name); 672 print_word(ctx, type._M_name); 673 } 674 else if (__builtin_strcmp(name, "type") == 0) 675 print_type(ctx, type._M_type, "<unknown type>"); 676 else 677 return false; 678 679 return true; 680 } 681 682 bool print_field(PrintContext & ctx,const char * name,const _Parameter::_Instance & inst)683 print_field(PrintContext& ctx, 684 const char* name, const _Parameter::_Instance& inst) 685 { 686 const _Parameter::_Type& type = inst; 687 if (print_field(ctx, name, type)) 688 { } 689 else if (__builtin_strcmp(name, "address") == 0) 690 { 691 char buf[64]; 692 int ret = __builtin_sprintf(buf, "%p", inst._M_address); 693 print_word(ctx, buf, ret); 694 } 695 else 696 return false; 697 698 return true; 699 } 700 701 void print_field(PrintContext & ctx,const _Parameter & param,const char * name)702 print_field(PrintContext& ctx, const _Parameter& param, const char* name) 703 { 704 assert(param._M_kind != _Parameter::__unused_param); 705 const int bufsize = 64; 706 char buf[bufsize]; 707 708 const auto& variant = param._M_variant; 709 switch (param._M_kind) 710 { 711 case _Parameter::__iterator: 712 { 713 const auto& iterator = variant._M_iterator; 714 if (print_field(ctx, name, iterator)) 715 { } 716 else if (__builtin_strcmp(name, "constness") == 0) 717 { 718 static const char* 719 constness_names[_Error_formatter::__last_constness] = 720 { 721 "<unknown constness>", 722 "constant", 723 "mutable" 724 }; 725 print_word(ctx, constness_names[iterator._M_constness]); 726 } 727 else if (__builtin_strcmp(name, "state") == 0) 728 { 729 static const char* 730 state_names[_Error_formatter::__last_state] = 731 { 732 "<unknown state>", 733 "singular", 734 "dereferenceable (start-of-sequence)", 735 "dereferenceable", 736 "past-the-end", 737 "before-begin", 738 "dereferenceable (start-of-reverse-sequence)", 739 "dereferenceable (reverse)", 740 "past-the-reverse-end" 741 }; 742 print_word(ctx, state_names[iterator._M_state]); 743 } 744 else if (__builtin_strcmp(name, "sequence") == 0) 745 { 746 assert(iterator._M_sequence); 747 int written = __builtin_sprintf(buf, "%p", iterator._M_sequence); 748 print_word(ctx, buf, written); 749 } 750 else if (__builtin_strcmp(name, "seq_type") == 0) 751 print_type(ctx, iterator._M_seq_type, "<unknown seq_type>"); 752 else 753 assert(false); 754 } 755 break; 756 757 case _Parameter::__sequence: 758 if (!print_field(ctx, name, variant._M_sequence)) 759 assert(false); 760 break; 761 762 case _Parameter::__integer: 763 if (__builtin_strcmp(name, "name") == 0) 764 { 765 assert(variant._M_integer._M_name); 766 print_word(ctx, variant._M_integer._M_name); 767 } 768 else 769 assert(false); 770 break; 771 772 case _Parameter::__string: 773 if (__builtin_strcmp(name, "name") == 0) 774 { 775 assert(variant._M_string._M_name); 776 print_word(ctx, variant._M_string._M_name); 777 } 778 else 779 assert(false); 780 break; 781 782 case _Parameter::__instance: 783 if (!print_field(ctx, name, variant._M_instance)) 784 assert(false); 785 break; 786 787 case _Parameter::__iterator_value_type: 788 if (!print_field(ctx, name, variant._M_iterator_value_type)) 789 assert(false); 790 break; 791 792 default: 793 assert(false); 794 break; 795 } 796 } 797 798 void print_description(PrintContext & ctx,const _Parameter::_Type & type)799 print_description(PrintContext& ctx, const _Parameter::_Type& type) 800 { 801 if (type._M_name) 802 { 803 print_literal(ctx, "\""); 804 print_word(ctx, type._M_name); 805 print_literal(ctx, "\""); 806 } 807 808 print_literal(ctx, " {\n"); 809 810 if (type._M_type) 811 { 812 print_literal(ctx, " type = "); 813 print_type(ctx, type._M_type, "<unknown type>"); 814 print_literal(ctx, ";\n"); 815 } 816 } 817 818 void print_description(PrintContext & ctx,const _Parameter::_Instance & inst)819 print_description(PrintContext& ctx, const _Parameter::_Instance& inst) 820 { 821 const int bufsize = 64; 822 char buf[bufsize]; 823 824 if (inst._M_name) 825 { 826 print_literal(ctx, "\""); 827 print_word(ctx, inst._M_name); 828 print_literal(ctx, "\" "); 829 } 830 831 int written 832 = __builtin_sprintf(buf, "@ 0x%p {\n", inst._M_address); 833 print_word(ctx, buf, written); 834 835 if (inst._M_type) 836 { 837 print_literal(ctx, " type = "); 838 print_type(ctx, inst._M_type, "<unknown type>"); 839 } 840 } 841 842 void print_description(PrintContext & ctx,const _Parameter & param)843 print_description(PrintContext& ctx, const _Parameter& param) 844 { 845 const int bufsize = 128; 846 char buf[bufsize]; 847 848 const auto& variant = param._M_variant; 849 switch (param._M_kind) 850 { 851 case _Parameter::__iterator: 852 { 853 const auto& ite = variant._M_iterator; 854 855 print_literal(ctx, "iterator "); 856 print_description(ctx, ite); 857 858 if (ite._M_type) 859 { 860 if (ite._M_constness != _Error_formatter::__unknown_constness) 861 { 862 print_literal(ctx, " ("); 863 print_field(ctx, param, "constness"); 864 print_literal(ctx, " iterator)"); 865 } 866 867 print_literal(ctx, ";\n"); 868 } 869 870 if (ite._M_state != _Error_formatter::__unknown_state) 871 { 872 print_literal(ctx, " state = "); 873 print_field(ctx, param, "state"); 874 print_literal(ctx, ";\n"); 875 } 876 877 if (ite._M_sequence) 878 { 879 print_literal(ctx, " references sequence "); 880 if (ite._M_seq_type) 881 { 882 print_literal(ctx, "with type '"); 883 print_field(ctx, param, "seq_type"); 884 print_literal(ctx, "' "); 885 } 886 887 int written 888 = __builtin_sprintf(buf, "@ 0x%p\n", ite._M_sequence); 889 print_word(ctx, buf, written); 890 } 891 892 print_literal(ctx, "}\n"); 893 } 894 break; 895 896 case _Parameter::__sequence: 897 print_literal(ctx, "sequence "); 898 print_description(ctx, variant._M_sequence); 899 900 if (variant._M_sequence._M_type) 901 print_literal(ctx, ";\n"); 902 903 print_literal(ctx, "}\n"); 904 break; 905 906 case _Parameter::__instance: 907 print_literal(ctx, "instance "); 908 print_description(ctx, variant._M_instance); 909 910 if (variant._M_instance._M_type) 911 print_literal(ctx, ";\n"); 912 913 print_literal(ctx, "}\n"); 914 break; 915 916 case _Parameter::__iterator_value_type: 917 print_literal(ctx, "iterator::value_type "); 918 print_description(ctx, variant._M_iterator_value_type); 919 print_literal(ctx, "}\n"); 920 break; 921 922 default: 923 break; 924 } 925 } 926 927 void print_string(PrintContext & ctx,const char * string,const _Parameter * parameters,std::size_t num_parameters)928 print_string(PrintContext& ctx, const char* string, 929 const _Parameter* parameters, std::size_t num_parameters) 930 { 931 const char* start = string; 932 const int bufsize = 128; 933 char buf[bufsize]; 934 int bufindex = 0; 935 936 while (*start) 937 { 938 if (isspace(*start)) 939 { 940 buf[bufindex++] = *start++; 941 buf[bufindex] = '\0'; 942 print_word(ctx, buf, bufindex); 943 bufindex = 0; 944 continue; 945 } 946 947 if (!num_parameters || *start != '%') 948 { 949 // Normal char or no parameter to look for. 950 buf[bufindex++] = *start++; 951 continue; 952 } 953 954 if (*++start == '%') 955 { 956 // Escaped '%' 957 buf[bufindex++] = *start++; 958 continue; 959 } 960 961 // We are on a parameter property reference, we need to flush buffer 962 // first. 963 if (bufindex != 0) 964 { 965 buf[bufindex] = '\0'; 966 print_word(ctx, buf, bufindex); 967 bufindex = 0; 968 } 969 970 // Get the parameter number 971 assert(*start >= '1' && *start <= '9'); 972 size_t param_index = *start - '0' - 1; 973 assert(param_index < num_parameters); 974 const auto& param = parameters[param_index]; 975 976 // '.' separates the parameter number from the field 977 // name, if there is one. 978 ++start; 979 if (*start != '.') 980 { 981 assert(*start == ';'); 982 ++start; 983 if (param._M_kind == _Parameter::__integer) 984 { 985 int written 986 = __builtin_sprintf(buf, "%ld", 987 param._M_variant._M_integer._M_value); 988 print_word(ctx, buf, written); 989 } 990 else if (param._M_kind == _Parameter::__string) 991 print_string(ctx, param._M_variant._M_string._M_value, 992 parameters, num_parameters); 993 continue; 994 } 995 996 // Extract the field name we want 997 const int max_field_len = 16; 998 char field[max_field_len]; 999 int field_idx = 0; 1000 ++start; 1001 while (*start != ';') 1002 { 1003 assert(*start); 1004 assert(field_idx < max_field_len - 1); 1005 field[field_idx++] = *start++; 1006 } 1007 ++start; 1008 field[field_idx] = '\0'; 1009 1010 print_field(ctx, param, field); 1011 } 1012 1013 // Might need to flush. 1014 if (bufindex) 1015 { 1016 buf[bufindex] = '\0'; 1017 print_word(ctx, buf, bufindex); 1018 } 1019 } 1020 } 1021 1022 namespace __gnu_debug 1023 { 1024 _Error_formatter& _M_message(_Debug_msg_id __id) const1025 _Error_formatter::_M_message(_Debug_msg_id __id) const throw () 1026 { 1027 return const_cast<_Error_formatter*>(this) 1028 ->_M_message(_S_debug_messages[__id]); 1029 } 1030 1031 void _M_error() const1032 _Error_formatter::_M_error() const 1033 { 1034 // Emit file & line number information 1035 bool go_to_next_line = false; 1036 PrintContext ctx; 1037 if (_M_file) 1038 { 1039 print_word(ctx, _M_file); 1040 print_literal(ctx, ":"); 1041 go_to_next_line = true; 1042 } 1043 1044 if (_M_line > 0) 1045 { 1046 char buf[64]; 1047 int written = __builtin_sprintf(buf, "%u:", _M_line); 1048 print_word(ctx, buf, written); 1049 go_to_next_line = true; 1050 } 1051 1052 if (go_to_next_line) 1053 print_literal(ctx, "\n"); 1054 1055 if (ctx._M_max_length) 1056 ctx._M_wordwrap = true; 1057 1058 if (_M_function) 1059 { 1060 print_literal(ctx, "In function:\n"); 1061 print_string(ctx, _M_function, nullptr, 0); 1062 print_literal(ctx, "\n"); 1063 ctx._M_first_line = true; 1064 print_literal(ctx, "\n"); 1065 } 1066 1067 // libstdc++/85768 1068 #if 0 //defined _GLIBCXX_HAVE_EXECINFO_H 1069 { 1070 void* stack[32]; 1071 int nb = backtrace(stack, 32); 1072 1073 // Note that we skip current method symbol. 1074 if (nb > 1) 1075 { 1076 print_literal(ctx, "Backtrace:\n"); 1077 auto symbols = backtrace_symbols(stack, nb); 1078 for (int i = 1; i < nb; ++i) 1079 { 1080 print_word(ctx, symbols[i]); 1081 print_literal(ctx, "\n"); 1082 } 1083 1084 free(symbols); 1085 ctx._M_first_line = true; 1086 print_literal(ctx, "\n"); 1087 } 1088 } 1089 #endif 1090 1091 print_literal(ctx, "Error: "); 1092 1093 // Print the error message 1094 assert(_M_text); 1095 print_string(ctx, _M_text, _M_parameters, _M_num_parameters); 1096 print_literal(ctx, ".\n"); 1097 1098 // Emit descriptions of the objects involved in the operation 1099 ctx._M_first_line = true; 1100 ctx._M_wordwrap = false; 1101 bool has_header = false; 1102 for (unsigned int i = 0; i < _M_num_parameters; ++i) 1103 { 1104 switch (_M_parameters[i]._M_kind) 1105 { 1106 case _Parameter::__iterator: 1107 case _Parameter::__sequence: 1108 case _Parameter::__instance: 1109 case _Parameter::__iterator_value_type: 1110 if (!has_header) 1111 { 1112 print_literal(ctx, "\nObjects involved in the operation:\n"); 1113 has_header = true; 1114 } 1115 print_description(ctx, _M_parameters[i]); 1116 break; 1117 1118 default: 1119 break; 1120 } 1121 } 1122 1123 abort(); 1124 } 1125 1126 #if !_GLIBCXX_INLINE_VERSION 1127 // Deprecated methods kept for backward compatibility. 1128 void _M_print_field(const _Error_formatter *,const char *) const1129 _Error_formatter::_Parameter::_M_print_field( 1130 const _Error_formatter*, const char*) const 1131 { } 1132 1133 void _M_print_description(const _Error_formatter *) const1134 _Error_formatter::_Parameter::_M_print_description(const _Error_formatter*) const 1135 { } 1136 1137 template<typename _Tp> 1138 void _M_format_word(char *,int,const char *,_Tp) const1139 _Error_formatter::_M_format_word(char*, int, const char*, _Tp) 1140 const throw () 1141 { } 1142 1143 void _M_print_word(const char *) const1144 _Error_formatter::_M_print_word(const char*) const 1145 { } 1146 1147 void _M_print_string(const char *) const1148 _Error_formatter::_M_print_string(const char*) const 1149 { } 1150 1151 void _M_get_max_length() const1152 _Error_formatter::_M_get_max_length() const throw () 1153 { } 1154 1155 // Instantiations. 1156 template 1157 void 1158 _Error_formatter::_M_format_word(char*, int, const char*, 1159 const void*) const; 1160 1161 template 1162 void 1163 _Error_formatter::_M_format_word(char*, int, const char*, long) const; 1164 1165 template 1166 void 1167 _Error_formatter::_M_format_word(char*, int, const char*, 1168 std::size_t) const; 1169 1170 template 1171 void 1172 _Error_formatter::_M_format_word(char*, int, const char*, 1173 const char*) const; 1174 #endif 1175 1176 } // namespace __gnu_debug 1177