Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Tom de Vries <tdevries@suse.de>, gdb-patches@sourceware.org
Subject: Re: [PATCH 3/3] [gdb/symtab] Tweak fix-up of truncated inline function block ranges
Date: Tue, 10 Mar 2026 16:05:06 +0000	[thread overview]
Message-ID: <875x738ybx.fsf@redhat.com> (raw)
In-Reply-To: <20260302114849.1797017-4-tdevries@suse.de>

Tom de Vries <tdevries@suse.de> writes:

> Consider test-case gdb.cp/step-and-next-inline.exp on ppc64le-linux.
>
> The corresponding source file step-and-next-inline.cc contains functions
> tree_check and get_alias_set:
> ...
>     35	#define TREE_TYPE(NODE) (*tree_check (NODE, 0))
>     36
>     37	inline tree *
>     38	tree_check (tree *t, int i)
>     39	{
>     40	  if (t->x != i)
>     41	    abort();
>     42	  tree *x = t;
>     43	  return x;
>     44	}
>     ...
>     48	int __attribute__((noinline, noclone))
>     49	get_alias_set (tree *t)
>     50	{
>     51	  if (t != NULL
>     52	      && TREE_TYPE (t).z != 1
>     53	      && TREE_TYPE (t).z != 2
>     54	      && TREE_TYPE (t).z != 3)
>     55	    return 0;
>     56	  return 1;
>     57	}
> ...
> as well as a trivial function main calling get_alias_set.
>
> Say we step into the first call to tree_check, and then step to the return
> at line 43:
> ...
> (gdb) s
> tree_check (i=0, t=0x10020030 <xx>) at step-and-next-inline.cc:40
> 40	  if (t->x != i)
> (gdb) s
> 43	  return x;
> (gdb)
> ...
>
> At that point, we have pc 0x1000071c:
> ...
> (gdb) p $pc
> $1 = (void (*)(void)) 0x1000071c <get_alias_set(tree*)+28>
> (gdb)
> ...
> and the backtrace looks like this:
> ...
>  (gdb) bt
>  #0  tree_check (i=<optimized out>, t=<optimized out>) at
>        step-and-next-inline.cc:43
>  #1  get_alias_set (t=t@entry=0x10020030 <xx>) at step-and-next-inline.cc:52
>  #2  0x0000000010000560 in main () at step-and-next-inline.cc:64
>  (gdb)
> ...
> which shows all 3 functions.
>
> This seems trivial, but it's not.
>
> All three calls to tree_check are inlined, and the first call is represented
> by:
> ...
>  <2><877>: Abbrev Number: 40 (DW_TAG_inlined_subroutine)
>     <878>   DW_AT_abstract_origin: <0x967>
>     <87c>   DW_AT_entry_pc    : 0x10000710
>     <884>   DW_AT_GNU_entry_view: 0
>     <885>   DW_AT_ranges      : 0xc
>     <88a>   DW_AT_call_line   : 52
> ...
> with DW_AT_ranges referring to:
> ...
> Contents of the .debug_rnglists section:
>
>     Offset   Begin    End
>     0000000c 0000000010000710 (base address)
>     00000015 0000000010000710 000000001000071c
>     00000018 000000001000077c 000000001000077c (start == end)
>     0000001b 0000000010000788 0000000010000790
>     0000001f <End of list>
> ...
>
> The range at offset 0x15 is [0x10000710, 0x1000071c), so address 0x1000071c
> does not fall in the range, and consequently the debug info does not consider
> 0x1000071c part of the inlined tree_check.
>
> However, since commit 8efed40efd6 ("gdb: fix-up truncated inline function
> block ranges"), gdb contains a fix in lnp_state_machine::record_line:
> ...
>   if (m_address != m_last_address
>       && m_stmt_at_address
>       && m_cu->producer_is_gcc ()
>       && (m_flags & LEF_IS_STMT) == 0)
>     dwarf_find_and_extend_inline_block_range (m_cu, m_last_address,
>                                               m_address, m_line);
> ...
> that looks at the corresponding line number information:
> ...
> File name                    Line number    Starting address    View    Stmt
> step-and-next-inline.cc               42          0x1000071c               x
> step-and-next-inline.cc               43          0x1000071c       1       x
> step-and-next-inline.cc               43          0x1000071c       2
> step-and-next-inline.cc               52          0x1000071c       3
> step-and-next-inline.cc               52          0x10000720
> ...
> and extends the range of the inlined tree_check to include
> [0x1000071c, 0x10000720).
>
> [ Please read the commit message of aforementioned commit to understand why
> the fix is correct. ]
>
> Let's look in more detail at how the call to
> dwarf_find_and_extend_inline_block_range is activated for the fix.  It's
> activated for the last entry (52/0x10000720), with:
> - m_last_address == 0x1000071c,
> - m_address == 0x10000720, and
> - m_line == 52 (matching the DW_AT_call_line).
>
> It's easy to see that for the last entry, (m_flags & LEF_IS_STMT) == 0 holds,
> because it doesn't have an x in the "Stmt" column.
>
> I found it less obvious that m_stmt_at_address also holds.
>
> [ The documentation clarifies that this is related to m_last_address:
> ....
>   /* Set to true when a previous line at the same address (using
>      m_last_address) had LEF_IS_STMT set in m_flags.  This is reset to false
>      when a line entry at a new address (m_address different to
>      m_last_address) is processed.  */
>   bool m_stmt_at_address = false;
> ...
>
> To get maximum clarity, I checked the value for each entry:
> ...
> address         m_stmt_at_address
> ---------------------------------
> before          false
> 42/0x1000071c   false->true
> 43/0x1000071c/1 true
> 43/0x1000071c/2 true
> 52/0x1000071c/3 true
> 52/0x10000720   true->false
> ...
>
> Again it's easy to relate the transitions for particular entries to the "Stmt"
> column.
>
> The tricky bit is that the transition takes place at the end of
> lnp_state_machine::record_line, so while processing entry 52/0x10000720, we
> sample m_stmt_at_address while it's still true. ]
>
> Likewise, the fix works for the second inlined call.
>
> But not for the third.  The debug info has the same problem, but the fix is
> not applied.
>
> The corresponding line info looks slightly different:
> ...
> File name                    Line number    Starting address    View    Stmt
> step-and-next-inline.cc               42          0x1000074c               x
> step-and-next-inline.cc               43          0x1000074c       1       x
> step-and-next-inline.cc               43          0x1000074c       2
> step-and-next-inline.cc               54          0x1000074c       3
> step-and-next-inline.cc               55          0x10000750
> ...
>
> In this case, dwarf_find_and_extend_inline_block_range gets called with:
> - m_last_address == 0x1000074c,
> - m_address == 0x10000750, and
> - m_line == 55,
> but since line 55 doesn't match DW_AT_call_line 54:
> ...
>  <2><918>: Abbrev Number: 44 (DW_TAG_inlined_subroutine)
>     <919>   DW_AT_abstract_origin: <0x967>
>     <91d>   DW_AT_entry_pc    : 0x10000740
>     <925>   DW_AT_GNU_entry_view: 0
>     <926>   DW_AT_low_pc      : 0x10000740
>     <92e>   DW_AT_high_pc     : 0xc
>     <937>   DW_AT_call_line   : 54
> ...
> the fix is not applied.
>
> I'm proposing the following simple tweak, to handle the third inlined call as
> well: instead of using m_line, use m_last_line.
>
> Tested on x86_64-linux and ppc64le-linux.
>
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33930

Hi Tom,

Thanks for looking at this failure.  Can you confirm which gcc version
you're using please.  I don't see the same failure on cfarm29 (from gcc
compile farm), using gcc 'gcc (Debian 14.2.0-19) 14.2.0'.  But that
step-and-next-inline test can change behaviour based on compiler
version, so I'm not surprised you're seeing failures on some specific
combinations.

Which is why I tried to write DWARF assembler tests to cover edge cases
as I found them, and I think it would be great if we could get such a
test to cover this fix too.  I'm happy to help with, or even write, the
test, once I can reproduce the failure.

I'll try some other ppc64le machines I have access too, maybe one of
those will have the right compiler version already installed, otherwise
I'll have to rebuild gcc once you let me know which version is causing
problems.

Thanks,
Andrew


  reply	other threads:[~2026-03-10 16:05 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-02 11:48 [PATCH 0/3] " Tom de Vries
2026-03-02 11:48 ` [PATCH 1/3] [gdb/symtab] Rename lnp_state_machine::m_last_line to m_last_recorded_line Tom de Vries
2026-03-02 11:48 ` [PATCH 2/3] [gdb/symtab] Re-add lnp_state_machine::m_last_line Tom de Vries
2026-03-02 11:48 ` [PATCH 3/3] [gdb/symtab] Tweak fix-up of truncated inline function block ranges Tom de Vries
2026-03-10 16:05   ` Andrew Burgess [this message]
2026-03-10 20:34     ` Tom de Vries
2026-03-14 14:22       ` Andrew Burgess
2026-03-14 14:53         ` Tom de Vries
2026-03-11 13:24     ` Tom de Vries
2026-03-11 15:13       ` Tom de Vries
2026-03-12  6:45         ` Tom de Vries
2026-03-12 12:07           ` Tom de Vries
2026-03-19 15:39   ` Andrew Burgess
2026-04-20 14:38     ` Tom de Vries

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=875x738ybx.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tdevries@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox