[RFA] no frame needed when computing address of subprogram

Joel Brobecker brobecker@adacore.com
Tue Jan 1 13:48:00 GMT 2008


Trying to compute the address of a procedure fails when the inferior
is not running:

        (gdb) p foo'address
        No registers.

To reproduce, use the trivial Ada program pasted at the end of
this email, and compile it with:

        % gnatmake -g foo

Then try the command above.

The problem is inside eval.c:evaluate_subexp_for_address, in the case
handling the OP_VAR_VALUE case. Unless we are in EVAL_AVOID_SIDE_EFFECT
mode, we end up doing:

      if (noside == EVAL_AVOID_SIDE_EFFECTS)
      [...]
      else
        return
          locate_var_value
          (var,
           block_innermost_frame (exp->elts[pc + 1].block));

In particular, we are trying to get the block_innermost_frame,
which doesn't exist in our case. The attached patch changes
that to first check that we need a frame to get the object
address, otherwise, we locate the value without a frame.

2008-01-01  Paul N. Hilfinger  <hilfinger@adacore.com>

        * eval.c (evaluate_subexp_for_address): Provide frame address to
        locate_var_value only if it will be needed.

I also wrote a tiny testcase that verifies the fix.

2008-01-01  Joel Brobecker  <brobecker@adacore.com>

        * gdb.ada/fun_addr/foo.adb: New file.
        * gdb.ada/fun_addr.exp: New testcase.

All tested on x86-linux, no regression.  The patch has also been in
AdaCore's tree since Aug 2003 (shame on us!).

OK to commit?

Thanks,
-- 
Joel

procedure Foo is
begin
   null;
end Foo;

-------------- next part --------------
Index: eval.c
===================================================================
--- eval.c	(revision 29)
+++ eval.c	(revision 30)
@@ -2150,11 +2150,13 @@ evaluate_subexp_for_address (struct expr
 	  return
 	    value_zero (type, not_lval);
 	}
-      else
+      else if (symbol_read_needs_frame (var))
 	return
 	  locate_var_value
 	  (var,
 	   block_innermost_frame (exp->elts[pc + 1].block));
+      else
+	return locate_var_value (var, NULL);
 
     case OP_SCOPE:
       tem = longest_to_int (exp->elts[pc + 2].longconst);
-------------- next part --------------
Index: gdb.ada/fun_addr.exp
===================================================================
--- gdb.ada/fun_addr.exp	(revision 0)
+++ gdb.ada/fun_addr.exp	(revision 31)
@@ -0,0 +1,44 @@
+# Copyright 2008 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 "fun_addr"
+set testfile "${testdir}/foo"
+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}
+
+# Verify that we are able to print the address of a function when
+# the inferior is *not* running (no frame).
+
+gdb_test "print foo'address" \
+         "0x\[0-9a-zA-Z\]+" \
+         "print foo'address"
+
+
Index: gdb.ada/fun_addr/foo.adb
===================================================================
--- gdb.ada/fun_addr/foo.adb	(revision 0)
+++ gdb.ada/fun_addr/foo.adb	(revision 31)
@@ -0,0 +1,19 @@
+--  Copyright 2008 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 Foo is
+begin
+   null;
+end Foo;


More information about the Gdb-patches mailing list