https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111243
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Richard Biener from comment #3) > it shouldn't make much difference when single-stepping > statements since the debugger should enter inlined bodies the same as > not inlined bodies? 'step' works OK, but 'next' and 'finish' are pretty useless. And if you can only use 'step' then you end up descending into constructors and destructors of temporaries and other uninteresting junk that isn't what you're trying to debug. For example, with this code: #include <chrono> #include <sstream> #include <assert.h> int main() { using namespace std::chrono; const sys_seconds expected = sys_days(2023y/August/9) + 20h + 44min; file_time<seconds> tp; minutes offset; std::string abbrev; std::istringstream is("002023-08-09 21:44 +01 BST!"); assert( is >> parse("%6F %R %z %Z", tp, abbrev, offset) ); } Compiled with -Og I get: $ gdb -q -ex start -ex n -ex n -ex n -ex n -ex n -ex step -ex step -ex step -ex step -ex step -ex step -ex step -ex step -ex step ./parse Reading symbols from ./parse... Temporary breakpoint 1 at 0x402296: file parse.cc, line 6. Starting program: /tmp/parse [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Temporary breakpoint 1, main () at parse.cc:6 6 { 9 file_time<seconds> tp; 12 std::string abbrev; 88 __new_allocator() _GLIBCXX_USE_NOEXCEPT { } 13 std::istringstream is("002023-08-09 21:44 +01 BST!"); 14 VERIFY( is >> parse("%6F %R %z %Z", tp, abbrev, offset) ); std::chrono::parse<char, std::char_traits<char>, std::allocator<char>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::chrono::time_point<std::filesystem::__file_clock, std::chrono::duration<long, std::ratio<1l, 1l> > > > (__offset=std::chrono::duration = { 73728min }, __abbrev="", __tp=std::chrono::file_time = { 0s [2174-01-01 00:00:00] }, __fmt=0x406324 "%6F %R %z %Z") at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2980 2980 &__offset); std::chrono::__detail::_Parse<std::chrono::time_point<std::filesystem::__file_clock, std::chrono::duration<long, std::ratio<1l, 1l> > >, char, std::char_traits<char>, std::allocator<char> >::_Parse (__offset=0x7fffffffd8d8, __abbrev=0x7fffffffd8b0, __tp=std::chrono::file_time = { 0s [2174-01-01 00:00:00] }, __fmt=0x406324 "%6F %R %z %Z", this=0x7fffffffd710) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2868 2868 _Parse(const _CharT* __fmt, _Parsable& __tp, std::chrono::__detail::operator>> (__is=..., __p=...) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2887 2887 operator>>(__stream_type& __is, _Parse&& __p) std::chrono::from_stream<char, std::char_traits<char>, std::chrono::duration<long, std::ratio<1l, 1l> >, std::allocator<char> > (__is=..., __fmt=0x406324 "%6F %R %z %Z", __tp=std::chrono::file_time = { 0s [2174-01-01 00:00:00] }, __abbrev=0x7fffffffd8b0, __offset=0x7fffffffd8d8) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2806 2806 from_stream(basic_istream<_CharT, _Traits>& __is, const _CharT* __fmt, std::chrono::from_stream<char, std::char_traits<char>, std::chrono::duration<long, std::ratio<1l, 1l> >, std::allocator<char> > (__is=..., __fmt=0x406324 "%6F %R %z %Z", __tp=std::chrono::sys_time = { 0s [1970-01-01 00:00:00] }, __abbrev=0x7fffffffd8b0, __offset=0x7fffffffd8d8) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2705 2705 from_stream(basic_istream<_CharT, _Traits>& __is, const _CharT* __fmt, 2716 __detail::_Parser_t<_Duration> __p(__need); std::chrono::__detail::_Parser<std::chrono::duration<long, std::ratio<1l, 1l> > >::_Parser (__need=23, this=0x7fffffffd680) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2136 2136 _Parser(__format::_ChronoParts __need) : _M_need(__need) { } std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<86400l, 1l> > >::time_point (this=0x7fffffffd688) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono.h:935 935 constexpr time_point() : __d(duration::zero()) 0x000000000040306b in std::chrono::__detail::_Parser<std::chrono::duration<long, std::ratio<1l, 1l> > >::operator()<char, std::char_traits<char>, std::allocator<char> > (this=this@entry=0x7fffffffd680, __is=..., __fmt=0x406324 "%6F %R %z %Z", __abbrev=0x7fffffffd8b0, __offset=__offset@entry=0x7fffffffd8d8) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:3007 3007 ios_base::iostate __err = ios_base::goodbit; I don't know what the __new_allocator constructor is doing there. The time_point constructor isn't interesting. If you replace any of those 'step' commands with 'next' you end up somewhere you don't want to be: $ gdb -q -ex start -ex n -ex n -ex n -ex n -ex n -ex step -ex step -ex step -ex n -ex step -ex step -ex step -ex step -ex step ./parse Reading symbols from ./parse... Temporary breakpoint 1 at 0x402296: file parse.cc, line 6. Starting program: /tmp/parse [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Temporary breakpoint 1, main () at parse.cc:6 6 { 9 file_time<seconds> tp; 12 std::string abbrev; 88 __new_allocator() _GLIBCXX_USE_NOEXCEPT { } 13 std::istringstream is("002023-08-09 21:44 +01 BST!"); 14 VERIFY( is >> parse("%6F %R %z %Z", tp, abbrev, offset) ); std::chrono::parse<char, std::char_traits<char>, std::allocator<char>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::chrono::time_point<std::filesystem::__file_clock, std::chrono::duration<long, std::ratio<1l, 1l> > > > (__offset=std::chrono::duration = { 73728min }, __abbrev="", __tp=std::chrono::file_time = { 0s [2174-01-01 00:00:00] }, __fmt=0x406324 "%6F %R %z %Z") at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2980 2980 &__offset); std::chrono::__detail::_Parse<std::chrono::time_point<std::filesystem::__file_clock, std::chrono::duration<long, std::ratio<1l, 1l> > >, char, std::char_traits<char>, std::allocator<char> >::_Parse (__offset=0x7fffffffd8d8, __abbrev=0x7fffffffd8b0, __tp=std::chrono::file_time = { 0s [2174-01-01 00:00:00] }, __fmt=0x406324 "%6F %R %z %Z", this=0x7fffffffd710) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2868 2868 _Parse(const _CharT* __fmt, _Parsable& __tp, std::chrono::__detail::operator>> (__is=..., __p=...) at /home/jwakely/gcc/14/include/c++/14.0.0/bits/chrono_io.h:2887 2887 operator>>(__stream_type& __is, _Parse&& __p) main () at /home/jwakely/gcc/14/include/c++/14.0.0/bits/ios_base.h:170 170 { return _Ios_Iostate(static_cast<int>(__a) & static_cast<int>(__b)); } std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_istringstream (this=0x7fffffffd730, __in_chrg=<optimized out>, __vtt_parm=<optimized out>) at /home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/sstream:626 626 ~basic_istringstream() 627 { } std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf (this=0x7fffffffd740, __in_chrg=<optimized out>) at /home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/sstream:79 79 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 627 { } 0x00007ffff7d4dd95 in std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf (this=0x7fffffffd740, __in_chrg=<optimized out>) at /home/jwakely/src/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/sstream:79 79 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> Suddenly we skip past all the inlined stuff to the end of main() and the destructors. I don't know how it got there, and I wrote most of that code.