From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Subject: [PATCH v2 5/5] [gdb/symtab] Tweak fix-up of truncated inline function block ranges
Date: Mon, 20 Apr 2026 15:46:08 +0200 [thread overview]
Message-ID: <20260420134608.2537059-6-tdevries@suse.de> (raw)
In-Reply-To: <20260420134608.2537059-1-tdevries@suse.de>
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_last_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).
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
---
gdb/dwarf2/line-program.c | 15 ++++++++++++++-
.../gdb.dwarf2/dw2-extend-inline-block.exp | 5 -----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/gdb/dwarf2/line-program.c b/gdb/dwarf2/line-program.c
index c8aaeb15ece..9199959c765 100644
--- a/gdb/dwarf2/line-program.c
+++ b/gdb/dwarf2/line-program.c
@@ -452,12 +452,25 @@ lnp_state_machine::record_line (bool end_sequence)
(end_sequence ? "\t(end sequence)" : ""));
}
+ /* Activate dwarf_find_and_extend_inline_block_range for line number info:
+
+ Line number Starting address View Stmt
+ 42 0x1000074c x
+ 43 0x1000074c 1 x
+ 43 0x1000074c 2
+ 54 0x1000074c 3
+ 55 0x10000750
+
+ at entry 55/0x10000750 with:
+ - m_last_address == 0x1000074c
+ - m_address == 0x10000750
+ - m_last_line == 54. */
if (m_address != m_last_address
&& m_stmt_at_last_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);
+ m_address, m_last_line);
file_entry *fe = current_file ();
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-extend-inline-block.exp b/gdb/testsuite/gdb.dwarf2/dw2-extend-inline-block.exp
index 481dfbdd134..dd41a9530c0 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-extend-inline-block.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-extend-inline-block.exp
@@ -600,11 +600,6 @@ foreach test_spec $test_list {
set build_dwarf_func [lindex $test_spec 1]
set check_block_func [lindex $test_spec 2]
- if {$build_dwarf_func == "build_dwarf_for_contiguous_block_3"} {
- # Work around PR gdb/33930.
- continue
- }
-
with_test_prefix $prefix {
set asm_file [standard_output_file ${testfile}-${suffix}.S]
$build_dwarf_func $asm_file
--
2.51.0
next prev parent reply other threads:[~2026-04-20 13:47 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-20 13:46 [PATCH v2 0/5] " Tom de Vries
2026-04-20 13:46 ` [PATCH v2 1/5] [gdb/symtab] Rename lnp_state_machine::m_last_line to m_last_recorded_line Tom de Vries
2026-04-20 13:46 ` [PATCH v2 2/5] [gdb/symtab] Re-add lnp_state_machine::m_last_line Tom de Vries
2026-04-20 13:46 ` [PATCH v2 3/5] [gdb/symtab] Simplify assignment in lnp_state_machine::record_line Tom de Vries
2026-04-20 13:46 ` [PATCH v2 4/5] [gdb/symtab] Add lnp_state_machine::m_stmt_at_last_address Tom de Vries
2026-04-20 13:46 ` Tom de Vries [this message]
2026-07-29 11:01 ` [PING][PATCH v2 0/5] [gdb/symtab] Tweak fix-up of truncated inline function block ranges 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=20260420134608.2537059-6-tdevries@suse.de \
--to=tdevries@suse.de \
--cc=gdb-patches@sourceware.org \
/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