]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/testsuite] Fix gdb.opt/inline-entry.exp with clang
authorTom de Vries <tdevries@suse.de>
Thu, 5 Mar 2026 20:59:28 +0000 (21:59 +0100)
committerTom de Vries <tdevries@suse.de>
Thu, 5 Mar 2026 20:59:28 +0000 (21:59 +0100)
I ran test-case gdb.opt/inline-entry.exp with clang, more specifically:
...
get_compiler_info: clang-17-0-6
...
and ran into:
...
(gdb) continue^M
Continuing.^M
^M
Breakpoint 2.1, bar (val=<optimized out>) at inline-entry.c:29^M
29        if (global == val)^M
(gdb) PASS: gdb.opt/inline-entry.exp: continue to bar
continue^M
Continuing.^M
^M
Breakpoint 2.3, bar (val=2) at inline-entry.c:29^M
29        if (global == val)^M
(gdb) FAIL: gdb.opt/inline-entry.exp: continue to foo
continue^M
Continuing.^M
^M
Breakpoint 3, foo (arg=arg@entry=1) at inline-entry.c:23^M
23        global += arg;^M
(gdb) FAIL: gdb.opt/inline-entry.exp: continue until exit
...

The problem is that the test-case expects two breakpoint locations for
function bar, and to hit one of them, but there are three and it hits two of
them.

This is due to the debug info, which for function bar:
...
 <1><25d>: Abbrev Number: 7 (DW_TAG_subprogram)
    <25e>   DW_AT_name        : bar
    <25f>   DW_AT_decl_file   : 1
    <260>   DW_AT_decl_line   : 27
    <261>   DW_AT_prototyped  : 1
    <261>   DW_AT_type        : <0x243>
    <265>   DW_AT_external    : 1
    <265>   DW_AT_inline      : 1       (inlined)
 <2><265>: Abbrev Number: 8 (DW_TAG_formal_parameter)
    <266>   DW_AT_name        : val
    <267>   DW_AT_decl_file   : 1
    <268>   DW_AT_decl_line   : 27
    <269>   DW_AT_type        : <0x243>
...
has three corresponding DW_TAG_inlined_subroutine DIEs:
...
 <2><27d>: Abbrev Number: 10 (DW_TAG_inlined_subroutine)
    <27e>   DW_AT_abstract_origin: <0x25d>
    <282>   DW_AT_ranges      : 0x31
    <283>   DW_AT_call_file   : 1
    <284>   DW_AT_call_line   : 38
 <2><285>: Abbrev Number: 11 (DW_TAG_inlined_subroutine)
    <286>   DW_AT_abstract_origin: <0x25d>
    <28a>   DW_AT_low_pc      : 0x114f
    <28b>   DW_AT_high_pc     : 0x5
    <28f>   DW_AT_call_file   : 1
    <290>   DW_AT_call_line   : 38
    <291>   DW_AT_call_column : 18
 <3><292>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <293>   DW_AT_const_value : 1
    <294>   DW_AT_abstract_origin: <0x265>
 <2><299>: Abbrev Number: 11 (DW_TAG_inlined_subroutine)
    <29a>   DW_AT_abstract_origin: <0x25d>
    <29e>   DW_AT_low_pc      : 0x1166
    <29f>   DW_AT_high_pc     : 0x7
    <2a3>   DW_AT_call_file   : 1
    <2a4>   DW_AT_call_line   : 38
    <2a5>   DW_AT_call_column : 30
 <3><2a6>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <2a7>   DW_AT_const_value : 2
    <2a8>   DW_AT_abstract_origin: <0x265>
...
while the source contains just two calls:
...
    35 int
    36 main (void)
    37 {
    38   if ((global && bar (1)) || bar (2))
    39     return 0;
    40   return 1;
    41 }
...

This is a bug in the debug info.

I don't see a way to work around this in gdb, so work around this in the
test-case by bailing out if there are more or less than two breakpoint
locations for function bar.

Tested on x86_64-linux.

Approved-By: Tom Tromey <tom@tromey.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33953

gdb/testsuite/gdb.opt/inline-entry.exp

index 937deecff99ceefd0ba162b519330900f2679997..588105491a75229c7e41a05dd0022a6f85090adc 100644 (file)
@@ -62,6 +62,24 @@ gdb_breakpoint "bar"
 set bp_bar_num [get_integer_valueof "\$bpnum" "*UNKNOWN*" \
                   "get number of bar breakpoint"]
 
+set ok 0
+gdb_test_multiple "info breakpoints $bp_bar_num" "" {
+    -re -wrap "\r\n2.3 .*" {
+       pass $gdb_test_name
+    }
+    -re -wrap "\r\n2.2 .*" {
+       set ok 1
+       pass $gdb_test_name
+    }
+    -re -wrap "" {
+       pass $gdb_test_name
+    }
+}
+if {!$ok} {
+    unsupported "incorrect amount of breakpoint locations"
+    return
+}
+
 gdb_breakpoint "foo"
 set bp_foo_num [get_integer_valueof "\$bpnum" "*UNKNOWN*" \
                   "get number of foo breakpoint"]