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.

Reply via email to