Fix breakpoint add on inlined function using function name.

Using this Ada example:

  package B is
    procedure Read_Small with Inline_Always;
  end B;

  package body B is
    Total : Natural := 0;
    procedure Read_Small is
    begin
      Total := Total + 1;
    end Read_Small;
  end B;

and

  with B;

  procedure M is
  begin
    B.Read_Small;
  end M;

% gnatmake -g -O0 -m m.adb -cargs -gnatn
% gdb m

Inserting a breakpoint on Read_Small inlined function does not work:

(gdb) b read_small
Breakpoint 1 at 0x40250e: file b.adb, line 5.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040250e in b.doit at b.adb:5
(gdb)

In this exemple we should have two breakpoints set, one in package B and
the other one in the inlined instance inside procedure M), like below:

(gdb) b read_small
Breakpoint 1 at 0x40250e: b.adb:5. (2 locations)
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>
1.1                         y     0x000000000040250e in b.doit at b.adb:5
1.2                         y     0x0000000000402540 in m at b.adb:5
(gdb)

Looking at the DWARF info for inlined instance of Read_Small:

<1><1526>: Abbrev Number: 2 (DW_TAG_subprogram)
    <1527>   DW_AT_name        : ([...], offset: 0x1e82): b__read_small
    <152b>   DW_AT_decl_file   : 2
    <152c>   DW_AT_decl_line   : 3
    <152d>   DW_AT_inline      : 3      (declared as inline and inlined)
[...]
 <2><1547>: Abbrev Number: 4 (DW_TAG_inlined_subroutine)
    <1548>   DW_AT_abstract_origin: <0x1526>
    <154c>   DW_AT_low_pc      : 0x402552
    <1554>   DW_AT_high_pc     : 0x2b
    <155c>   DW_AT_call_file   : 1
    <155d>   DW_AT_call_line   : 5
 <2><155e>: Abbrev Number: 0

During the parsing of DWARF info in order to produce partial DIE linked
list, the DW_TAG_inlined_subroutine were skipped thus not present in the
final partial dies.
Taking DW_TAG_inlined_subroutine in account during the parsing process
fixes the problem.

gdb/ChangeLog:

        * dwarf2read.c (scan_partial_symbols, add_partial_symbol)
        (add_partial_subprogram, load_partial_dies): Add
        DW_TAG_inlined_subroutine handling.

gdb/testsuite/ChangeLog:

        * gdb.ada/bp_inlined_func: New testcase.
This commit is contained in:
Xavier Roirand 2017-12-11 10:03:45 +01:00
parent 6cef73f96f
commit b1dc1806fa
7 changed files with 188 additions and 8 deletions

View File

@ -9065,11 +9065,13 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
if (pdi->name != NULL || pdi->tag == DW_TAG_namespace
|| pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type
|| pdi->tag == DW_TAG_imported_unit)
|| pdi->tag == DW_TAG_imported_unit
|| pdi->tag == DW_TAG_inlined_subroutine)
{
switch (pdi->tag)
{
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
add_partial_subprogram (pdi, lowpc, highpc, set_addrmap, cu);
break;
case DW_TAG_constant:
@ -9304,6 +9306,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
switch (pdi->tag)
{
case DW_TAG_inlined_subroutine:
case DW_TAG_subprogram:
addr = gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr);
if (pdi->is_external || cu->language == language_ada)
@ -9501,12 +9504,12 @@ add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
scan_partial_symbols (pdi->die_child, lowpc, highpc, set_addrmap, cu);
}
/* Read a partial die corresponding to a subprogram and create a partial
symbol for that subprogram. When the CU language allows it, this
routine also defines a partial symbol for each nested subprogram
that this subprogram contains. If SET_ADDRMAP is true, record the
covered ranges in the addrmap. Set *LOWPC and *HIGHPC to the lowest
and highest PC values found in PDI.
/* Read a partial die corresponding to a subprogram or an inlined
subprogram and create a partial symbol for that subprogram.
When the CU language allows it, this routine also defines a partial
symbol for each nested subprogram that this subprogram contains.
If SET_ADDRMAP is true, record the covered ranges in the addrmap.
Set *LOWPC and *HIGHPC to the lowest and highest PC values found in PDI.
PDI may also be a lexical block, in which case we simply search
recursively for subprograms defined inside that lexical block.
@ -9518,7 +9521,7 @@ add_partial_subprogram (struct partial_die_info *pdi,
CORE_ADDR *lowpc, CORE_ADDR *highpc,
int set_addrmap, struct dwarf2_cu *cu)
{
if (pdi->tag == DW_TAG_subprogram)
if (pdi->tag == DW_TAG_subprogram || pdi->tag == DW_TAG_inlined_subroutine)
{
if (pdi->has_pc_info)
{
@ -9566,6 +9569,7 @@ add_partial_subprogram (struct partial_die_info *pdi,
{
fixup_partial_die (pdi, cu);
if (pdi->tag == DW_TAG_subprogram
|| pdi->tag == DW_TAG_inlined_subroutine
|| pdi->tag == DW_TAG_lexical_block)
add_partial_subprogram (pdi, lowpc, highpc, set_addrmap, cu);
pdi = pdi->die_sibling;
@ -18409,6 +18413,7 @@ load_partial_dies (const struct die_reader_specs *reader,
&& abbrev->tag != DW_TAG_constant
&& abbrev->tag != DW_TAG_enumerator
&& abbrev->tag != DW_TAG_subprogram
&& abbrev->tag != DW_TAG_inlined_subroutine
&& abbrev->tag != DW_TAG_lexical_block
&& abbrev->tag != DW_TAG_variable
&& abbrev->tag != DW_TAG_namespace

View File

@ -0,0 +1,59 @@
# Copyright 2017-2018 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
load_lib "ada.exp"
standard_ada_testfile foo
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } {
return -1
}
clean_restart ${testfile}
if ![runto_main] then {
fail "Cannot run to main, testcase aborted"
return 0
}
# Check that inserting breakpoint on read_small inlined function inserts
# 4 breakpoints.
gdb_test "break read_small" \
"Breakpoint $decimal at $hex: read_small\\. \\(4 locations\\)" \
"set breakpoint at read_small"
# We do not verify each breakpoint info, but use continue commands instead
# to verify that we properly stop on each expected breakpoint.
gdb_test "continue" \
"Breakpoint $decimal, b\\.doit \\(\\).*" \
"Hitting first call of read_small"
gdb_test "continue" \
"Breakpoint $decimal, foo \\(\\).*" \
"Hitting second call of read_small"
gdb_test "continue" \
"Breakpoint $decimal, c\\.c_doit \\(\\).*" \
"Hitting third call of read_small"
gdb_test "continue" \
"Breakpoint $decimal, c\\.c_doit2 \\(\\).*" \
"Hitting fourth call of read_small"
gdb_test "continue" \
"Continuing\..*$inferior_exited_re.*" \
"continuing to program completion"

View File

@ -0,0 +1,28 @@
-- Copyright 2017-2018 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
package body B is
Total : Natural := 0;
procedure Read_Small is
begin
Total := Total + 1; -- BREAK
end Read_Small;
procedure Doit is
begin
Read_Small;
null;
end Doit;
end B;

View File

@ -0,0 +1,19 @@
-- Copyright 2017-2018 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
package B is
procedure Read_Small with Inline_Always;
procedure Doit;
end B;

View File

@ -0,0 +1,27 @@
-- Copyright 2017-2018 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
with B;
package body C is
procedure C_Doit is
begin
B.Read_Small;
C_Doit2;
end;
procedure C_Doit2 is
begin
B.Read_Small;
end;
end C;

View File

@ -0,0 +1,19 @@
-- Copyright 2017-2018 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
package C is
procedure C_Doit;
procedure C_Doit2;
end C;

View File

@ -0,0 +1,23 @@
-- Copyright 2017-2018 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
with B; use B;
with C;
procedure FOO is
begin
Doit;
B.Read_Small;
C.C_Doit;
end FOO;