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: Sat, 14 Mar 2026 14:22:59 +0000 [thread overview]
Message-ID: <87pl567anw.fsf@redhat.com> (raw)
In-Reply-To: <40a83dad-1a3a-4b68-b84e-9b7cc3b9f866@suse.de>
Tom de Vries <tdevries@suse.de> writes:
> On 3/10/26 5:05 PM, Andrew Burgess wrote:
>> 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.
> Hi Andrew,
>
> As stated here ( https://sourceware.org/bugzilla/show_bug.cgi?id=33930#c2 )
> ...
> Used compiler version:
> ...
> [vries@cfarm120 gdb]$ gcc --version
> gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-11)
> ...
>
> So I'd try cfarm120.
Thanks. Just wanted to say I've not forgotten this patch. I managed to
reproduce the failure, and I understand what's going on now. I'm going
to think about this some more next week.
Thanks,
Andrew
next prev parent reply other threads:[~2026-03-14 14:23 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
2026-03-10 20:34 ` Tom de Vries
2026-03-14 14:22 ` Andrew Burgess [this message]
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=87pl567anw.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