[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 Jonathan Wakely changed: What|Removed |Added Status|RESOLVED|NEW Resolution|FIXED |--- Target Milestone|5.5 |--- --- Comment #21 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #17) > The only thing remaining is to add checks for debug iterators to detect when > they are past-the-end. Re-opening, I forgot about this part.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 Jonathan Wakely changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED Target Milestone|--- |5.5 --- Comment #20 from Jonathan Wakely --- Fixed for 5.5
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #19 from Jonathan Wakely --- Author: redi Date: Thu May 18 09:23:43 2017 New Revision: 248183 URL: https://gcc.gnu.org/viewcvs?rev=248183&root=gcc&view=rev Log: PR59170 make pretty printers check for singular iterators Backport from mainline 2016-12-15 Jonathan Wakely PR libstdc++/59170 * python/libstdcxx/v6/printers.py (StdListIteratorPrinter.to_string) (StdSlistIteratorPrinter.to_string, StdVectorIteratorPrinter.to_string) (StdRbtreeIteratorPrinter.to_string) (StdDequeIteratorPrinter.to_string): Add check for value-initialized iterators. * testsuite/libstdc++-prettyprinters/simple.cc: Test them. * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise. Modified: branches/gcc-5-branch/libstdc++-v3/ChangeLog branches/gcc-5-branch/libstdc++-v3/python/libstdcxx/v6/printers.py branches/gcc-5-branch/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc branches/gcc-5-branch/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #18 from Jonathan Wakely --- Author: redi Date: Wed Feb 15 13:38:48 2017 New Revision: 245481 URL: https://gcc.gnu.org/viewcvs?rev=245481&root=gcc&view=rev Log: PR59170 make pretty printers check for singular iterators Backport from mainline 2016-12-15 Jonathan Wakely PR libstdc++/59170 * python/libstdcxx/v6/printers.py (StdListIteratorPrinter.to_string) (StdSlistIteratorPrinter.to_string, StdVectorIteratorPrinter.to_string) (StdRbtreeIteratorPrinter.to_string) (StdDequeIteratorPrinter.to_string): Add check for value-initialized iterators. * testsuite/libstdc++-prettyprinters/simple.cc: Test them. * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise. Modified: branches/gcc-6-branch/libstdc++-v3/ChangeLog branches/gcc-6-branch/libstdc++-v3/python/libstdcxx/v6/printers.py branches/gcc-6-branch/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc branches/gcc-6-branch/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #17 from Jonathan Wakely --- I've added some more checks for non-debug iterators. The only thing remaining is to add checks for debug iterators to detect when they are past-the-end.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #16 from Jonathan Wakely --- Author: redi Date: Thu Dec 15 14:13:36 2016 New Revision: 243692 URL: https://gcc.gnu.org/viewcvs?rev=243692&root=gcc&view=rev Log: PR59170 make pretty printers check for singular iterators PR libstdc++/59170 * python/libstdcxx/v6/printers.py (StdListIteratorPrinter.to_string) (StdSlistIteratorPrinter.to_string, StdVectorIteratorPrinter.to_string) (StdRbtreeIteratorPrinter.to_string) (StdDequeIteratorPrinter.to_string): Add check for value-initialized iterators. * testsuite/libstdc++-prettyprinters/simple.cc: Test them. * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/python/libstdcxx/v6/printers.py trunk/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc trunk/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #15 from Jonathan Wakely --- Author: redi Date: Wed Dec 14 15:17:57 2016 New Revision: 243650 URL: https://gcc.gnu.org/viewcvs?rev=243650&root=gcc&view=rev Log: Make printers detect invalid debug mode iterators PR libstdc++/59170 * python/libstdcxx/v6/printers.py (StdDebugIteratorPrinter): Use _M_sequence and _M_version to detect invalid iterators. * testsuite/libstdc++-prettyprinters/debug.cc: Test debug mode vector and test invalid iterators. * testsuite/libstdc++-prettyprinters/debug_cxx11.cc: New test. Added: trunk/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug_cxx11.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/python/libstdcxx/v6/printers.py trunk/libstdc++-v3/testsuite/libstdc++-prettyprinters/debug.cc
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #14 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #7) > "print it" should not automatically dereference. The Python code that registers the printers for iterators even says: # These shouldn't be necessary, if GDB "print *i" worked. # But it often doesn't, so here they are. i.e. automatically dereferencing is a hack due to the fact that trying to do it inside GDB doesn't work. But with Xmethods we can make "print *i" work, even when the relevant operator definition is inlined and not in the debug info.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #13 from Jonathan Wakely --- (In reply to Jan Kratochvil from comment #11) > (In reply to Jonathan Wakely from comment #9) > > Most developers don't even know the debug mode exists. > > That's a problem communicating it to users. -O0 -g would be best to always > use -D_GLIBCXX_DEBUG if there is a way how to solve the ABI compatibility > problem. That's a HUGE if. There is no plan to make debug mode ABI compatibile, so it's impossible to use in many cases (e.g. linking to pre-built third-party libs that use C++ types in the API). Anyway, I am testing some patches to improve printing of invalid iterators (both debug mode and normal).
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #12 from Jan Kratochvil --- (In reply to Jonathan Wakely from comment #7) > That doesn't help: > > std::vector::iterator it; > { > std::vector v{1}; > it = v.begin(); > } > > The iterator is safely initialized, safely updated to a valid value, but is > not dereferenceable after the last statement. > > "print it" should not automatically dereference. Therefore (at least with -D_GLIBCXX_DEBUG) "print it" (IMO) should automatically dereference as it is safe - the iterator always does know if it is valid or not.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #11 from Jan Kratochvil --- (In reply to Jonathan Wakely from comment #9) > Most developers don't even know the debug mode exists. That's a problem communicating it to users. -O0 -g would be best to always use -D_GLIBCXX_DEBUG if there is a way how to solve the ABI compatibility problem. > I don't know what "code for debugging with pretty printers" means. Users > don't do anything special for debugging with pretty printers, There are various kinds of bugs/crashes I am used to debug. For code where I benefit from pretty printers I can+do use -O0 -g -D_GLIBCXX_DEBUG during edit-compile-debug cycles. For system packages crashes (-O2 -g, no _GLIBCXX_DEBUG) there are so many variables, missing method instantiations and interleaved code there is no chance to start investigating data structures so thoroughly to benefit even from a pretty printer. YMMV. (In reply to Jonathan Wakely from comment #10) > This is all already done, isn't it? Wow, it really is. I remembered some worse experience with it. Thank you very much for this notification.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #10 from Jonathan Wakely --- (In reply to Jan Kratochvil from comment #6) > This all depends more on a different non-pretty-printers feature I plan to > file for libstdc++ for years but I have never done so yet. With > -D_GLIBCXX_DEBUG the iterators could be memory-managed - they already track > their container by _M_sequence. The container could also track all its live > iterators, elements could track iterators pointing at them (and properly > invalidate them upon container updates) etc. Deleting the container would > invalidate all its iterators etc. Accessing an invalidated iterator would > then immediately assert. This is all already done, isn't it? Containers keep a list of active iterators (see _Safe_sequence_base::_M_iterators) which are automatically invalidated by the relevant container operations.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #9 from Jonathan Wakely --- (In reply to Jan Kratochvil from comment #8) > (In reply to Jonathan Wakely from comment #7) > > But most code isn't compiled with debug mode enabled. > > IMO all code for debugging with pretty printers is compiled with debug mode > enabled. That's absolutely not true. Most developers don't even know the debug mode exists. Most C++ code being debugged with GDB is compiled with -O0 -g or with -Og -g, but not debug mode. In that scenario the pretty printers will be enabled, but won't be able to detect invalid iterators. I don't know what "code for debugging with pretty printers" means. Users don't do anything special for debugging with pretty printers, they just use GDB and the printers are automatically active. And they automatically dereference iterators, with unpleasant results.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #8 from Jan Kratochvil --- (In reply to Jonathan Wakely from comment #7) > That doesn't help: > > std::vector::iterator it; > { > std::vector v{1}; > it = v.begin(); > } > > The iterator is safely initialized, safely updated to a valid value, but is > not dereferenceable after the last statement. At the "}" line container gets destructed which should invalidate "it" according to my last paragraph of Comment 6 and then "print it" would print a message "invalidated iterator". Sure fully-managed iterators are a larger feature request than this PR. > "print it" should not automatically dereference. This is GCC maintainers opinion; not mine. > But most code isn't compiled with debug mode enabled. IMO all code for debugging with pretty printers is compiled with debug mode enabled. The other case are Linux system -O2 -g packages which are not really debuggable up to the level of C++ containers at all. One is glad to get a partially readable backtrace for a crash of a system package.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #7 from Jonathan Wakely --- (In reply to Jan Kratochvil from comment #6) > (In reply to Jonathan Wakely from comment #5) > > I think it's simply wrong to automatically dereference iterators. GDB > > doesn't do that when printing pointers, so why do the pretty printers do it > > for iterators? > > The difference is that pointer is memory-unmanaged and this is not fixable. > But C++ data structures have memory management (at least they should have). That doesn't help: std::vector::iterator it; { std::vector v{1}; it = v.begin(); } The iterator is safely initialized, safely updated to a valid value, but is not dereferenceable after the last statement. "print it" should not automatically dereference. > > There are loads of cases where it does the wrong thing, not only for > > past-the-end iterators but also for default-constructed ones that might > > contain uninitialized pointers. > > Default-constructed iterators can be detected by _M_sequence==nullptr > (-D_GLIBCXX_DEBUG). It works for the example above as well, and I'll make the printers do that. But most code isn't compiled with debug mode enabled.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #6 from Jan Kratochvil --- (In reply to Jonathan Wakely from comment #5) > I think it's simply wrong to automatically dereference iterators. GDB > doesn't do that when printing pointers, so why do the pretty printers do it > for iterators? The difference is that pointer is memory-unmanaged and this is not fixable. But C++ data structures have memory management (at least they should have). > There are loads of cases where it does the wrong thing, not only for > past-the-end iterators but also for default-constructed ones that might > contain uninitialized pointers. Default-constructed iterators can be detected by _M_sequence==nullptr (-D_GLIBCXX_DEBUG). This all depends more on a different non-pretty-printers feature I plan to file for libstdc++ for years but I have never done so yet. With -D_GLIBCXX_DEBUG the iterators could be memory-managed - they already track their container by _M_sequence. The container could also track all its live iterators, elements could track iterators pointing at them (and properly invalidate them upon container updates) etc. Deleting the container would invalidate all its iterators etc. Accessing an invalidated iterator would then immediately assert. Then it is safe to pretty print any iterator as the iterator itself knows whether it has been invalidated or not.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 --- Comment #5 from Jonathan Wakely --- I think it's simply wrong to automatically dereference iterators. GDB doesn't do that when printing pointers, so why do the pretty printers do it for iterators? There are loads of cases where it does the wrong thing, not only for past-the-end iterators but also for default-constructed ones that might contain uninitialized pointers.
[Bug libstdc++/59170] pretty printers: end iterator invalid pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59170 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2016-12-13 Component|debug |libstdc++ Ever confirmed|0 |1