[RFA/dwarf] save nested Ada subprograms as global symbol
Joel Brobecker
brobecker@adacore.com
Thu Dec 27 18:10:00 GMT 2007
Hello,
This is part of what I hope will be a string of patches that should
bring the GDB close to the AdaCore version of GDB in terms of Ada support.
My hope is to find the time this year to reach that level, which
would then make it easier for us to keep Ada support between our tree
and the FSF tree synchronized.
The Ada language provides support for nested subprograms. Consider
the following simple program:
procedure Hello is
procedure First is
begin
null;
end First;
procedure Second is
begin
First;
end Second;
procedure Third is
begin
Second;
end Third;
begin
Third;
end Hello;
This is a trivial program, where the main procedure (Hello) contains
three nested procedures (Third, Second, and First). To compile it,
do the following:
% gnatmake -g hello
The problem is trying to break on First:
% gdb hello
(gdb) break first
Function "first" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
What we'd like to be able to do is:
(gdb) b first
Breakpoint 1 at 0x804954a: file hello.adb, line 6.
(gdb) run
Starting program: /home/no-backup/brobecke/ada-fsf/nested/hello
Breakpoint 1, hello.first () at hello.adb:6
6 end First;
To achieve this, we modified dwarf2read to store all Ada subprograms
in the global scope, even the ones that are not "external". Another
approach that was considered was to modify the Ada lookup routines
to extend the search to non-global/static scopes, but I'm concerned
about performance.
In practice, even though these routines are indeed local to our
procedure in the Ada program, we want to be flexible with the user
in the debugger, and treat these procedures as global, so that the
user can break inside them without specifying the scope or having
to be in the scope where the function is defined.
This is what the attached patch does:
2007-12-27 Joel Brobecker <brobecker@adacore.com>
* dwarf2read.c (add_partial_symbol): Always store all Ada subprograms
in the global scope.
(new_symbol): Likewise.
Tested on x86-linux, no regression. OK to commit?
I am also attaching a testcase that fails without this patch:
2007-12-27 Joel Brobecker <brobecker@adacore.com>
* gdb.ada/nested/hello.adb: New file.
* gdb.ada/nested.exp: New testcase.
* gdb.ada/Makefile.in (EXECUTABLES): Update list.
Tested on x86-linux as well.
Thanks,
--
Joel
-------------- next part --------------
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.243
diff -u -p -r1.243 dwarf2read.c
--- dwarf2read.c 22 Dec 2007 20:58:30 -0000 1.243
+++ dwarf2read.c 27 Dec 2007 05:46:35 -0000
@@ -1898,8 +1898,12 @@ add_partial_symbol (struct partial_die_i
switch (pdi->tag)
{
case DW_TAG_subprogram:
- if (pdi->is_external)
+ if (pdi->is_external || cu->language == language_ada)
{
+ /* brobecker/2007-12-26: Normally, only "external" DIEs are part
+ of the global scope. But in Ada, we want to be able to access
+ nested procedures globally. So all Ada subprograms are stored
+ in the global scope. */
/*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
mst_text, objfile); */
psym = add_psymbol_to_list (actual_name, strlen (actual_name),
@@ -7288,8 +7292,15 @@ new_symbol (struct die_info *die, struct
finish_block. */
SYMBOL_CLASS (sym) = LOC_BLOCK;
attr2 = dwarf2_attr (die, DW_AT_external, cu);
- if (attr2 && (DW_UNSND (attr2) != 0))
+ if ((attr2 && (DW_UNSND (attr2) != 0))
+ || cu->language == language_ada)
{
+ /* Subprograms marked external are stored as a global symbol.
+ Ada subprograms, whether marked external or not, are always
+ stored as a global symbol, because we want to be able to
+ access them globally. For instance, we want to be able
+ to break on a nested subprogram without having to
+ specify the context. */
add_symbol_to_list (sym, &global_symbols);
}
else
-------------- next part --------------
-- Copyright 2007 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/>.
procedure Hello is
procedure First is
begin
null;
end First;
procedure Second is
begin
First;
end Second;
procedure Third is
begin
Second;
end Third;
begin
Third;
end Hello;
-------------- next part --------------
# Copyright 2007 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/>.
if $tracelevel then {
strace $tracelevel
}
load_lib "ada.exp"
set testdir "nested"
set testfile "${testdir}/hello"
set srcfile ${srcdir}/${subdir}/${testfile}.adb
set binfile ${objdir}/${subdir}/${testfile}
file mkdir ${objdir}/${subdir}/${testdir}
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } {
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
set any_nb "\[0-9\]+"
set any_addr "0x\[0-9a-zA-Z\]+"
# Try breaking on a nested function.
gdb_test "break first" \
"Breakpoint $any_nb at $any_addr: file .*hello.adb, line $any_nb." \
"break on nested function First"
-------------- next part --------------
Index: gdb.ada/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.ada/Makefile.in,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile.in
--- gdb.ada/Makefile.in 26 Dec 2007 14:21:53 -0000 1.3
+++ gdb.ada/Makefile.in 27 Dec 2007 07:37:36 -0000
@@ -11,6 +11,7 @@ EXECUTABLES = \
exec_changed/second \
fixed_points/fixed_points \
frame_args/foo \
+ nested/hello \
null_record/null_record \
packed_array/pa \
print_chars/foo \
More information about the Gdb-patches
mailing list