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