[Bug gdb/33981] [gdb] missing print frame when stepping out of function

cvs-commit at gcc dot gnu.org sourceware-bugzilla@sourceware.org
Tue Apr 14 20:36:32 GMT 2026


https://sourceware.org/bugzilla/show_bug.cgi?id=33981

--- Comment #3 from Sourceware Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3959bfb8a5238692cd910324383c947194a5cdd6

commit 3959bfb8a5238692cd910324383c947194a5cdd6
Author: Tom de Vries <tdevries@suse.de>
Date:   Tue Apr 14 22:36:09 2026 +0200

    gdb: fix missing print frame when stepping out of function

    Consider test-case gdb.dwarf2/dw2-extend-inline-block.exp,
    specifically the "contiguous block" prefix part, which can be stepped
    through like this:

    ...
      $ gdb -q
outputs/gdb.dwarf2/dw2-extend-inline-block/dw2-extend-inline-block-5
      Reading symbols from dw2-extend-inline-block-5...
      (gdb) start
      ... snip ...
      Temporary breakpoint 1, main () at dw2-extend-inline-block.c:35
      35      /* main:2 */
      (gdb) s
      36      /* main:3 */ foo ();                          /* foo call line */
      (gdb)
      foo () at dw2-extend-inline-block.c:26
      26      /* foo:1 */
      (gdb) s
      27      /* foo:2 */
      (gdb) s
      28      /* foo:3 */
      (gdb) s
      main () at dw2-extend-inline-block.c:37
      37      /* main:4 */
      (gdb)
    ...

    If we slightly modify the line program:

    ...
            DW_LNE_set_address main_4
    +       DW_LNS_advance_line 1
            DW_LNS_copy

            DW_LNE_set_address main_5
    -       DW_LNS_advance_line 1
            DW_LNS_negate_stmt
            DW_LNS_copy
    ...

    we change the 36/0x401165 entry into a 37/0x401165 entry:

    ...
      File name                     Line number    Starting address    View   
Stmt
      dw2-extend-inline-block.c              34            0x401116            
  x
      dw2-extend-inline-block.c              35            0x401129            
  x
      dw2-extend-inline-block.c              26            0x401138            
  x
      dw2-extend-inline-block.c              27            0x401147            
  x
      dw2-extend-inline-block.c              28            0x401156            
  x
      dw2-extend-inline-block.c              36            0x401156
     -dw2-extend-inline-block.c              36            0x401165
     +dw2-extend-inline-block.c              37            0x401165
      dw2-extend-inline-block.c              37            0x401174            
  x
      dw2-extend-inline-block.c              38            0x401183            
  x
      dw2-extend-inline-block.c              39            0x401192            
  x
      dw2-extend-inline-block.c              40            0x4011a1            
  x
      dw2-extend-inline-block.c               -            0x4011b7
    ...

    As it happens, the fix to extend truncated inlined function blocks
    doesn't work in this case.  This is PR gdb/33930.

    We can work around this by making sure that the inlined function block
    isn't truncated in the first place:

    ...
    -                       DW_AT_high_pc main_3 addr
    +                       DW_AT_high_pc main_4 addr
    ...

    But then we still run into PR gdb/33981: the problem that gdb doesn't
    notify us when stepping out of foo:

    ...
      (gdb) step^M
      28        /* foo:3 */^M
      (gdb) step^M
      37        /* main:4 */^M
      (gdb)
    ...

    What happens is that the slightly different line program triggers a
    different stepping path, which includes a case of "stepped to a
    different frame, but it's not the start of a statement", which
    refreshes the stepping info and consequently updates
    tp->control.step_frame_id to the frame id of main.

    So by the time we're stopped at line 37, and are trying to figure out
    what to print in print_stop_location, this condition evaluates to
    true:

    ...
          if (tp->control.stop_step
              && (tp->control.step_frame_id
                  == get_frame_id (get_current_frame ()))
              && (tp->control.step_start_function
                  == find_symbol_for_pc (tp->stop_pc ())))
    ...

    and we get:

    ...
          /* Finished step in same frame and same file, just print source
             line.  */
          source_flag = SRC_LINE;
    ...

    It's good to realize here that because foo is inlined into main,
    tp->control.step_start_function is not foo but main, so consequently
    the step_start_function check (which checks if we are still in the
    same function) also passes, even though we actually stepped from foo
    into main.

    The problem is the use of find_symbol_for_pc, this function
    deliberately skips over inline frames and returns the symbol for the
    innermost non-inline frame.

    It might be tempting to think that we should switch to use
    find_symbol_for_pc_sect_maybe_inline, which will return the symbol for
    an inline frame, but this also has problems, specifically, attempting
    this caused a regression in gdb.opt/inline-cmds.exp.  The previous
    version of this patch, which showed the regression can be found here:

     
https://inbox.sourceware.org/gdb-patches/20260331132342.1050954-1-tdevries@suse.de

    At a given $pc the inferior might be reported as being within an
    inline frame, or it might be reported as being in the containing
    non-inline frame.  When the user performs a 'step' the
    step_start_function needs to be set based on the function symbol of
    the frame the inferior is actually reported in.  And we have a
    function that gives us this information, get_frame_function.  So
    instead of looking up the step_start_function based on the $pc value,
    set it based on the frame.

    Test gdb.dwarf2/dw2-extend-inline-block.exp is extended with the
    additional test case described above.

    Tested on x86_64-linux.

    Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
    Approved-By: Andrew Burgess <aburgess@redhat.com>
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33930
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33981

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Gdb-prs mailing list