This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix Python access to inlined frames


Hi,

the python interface still have not dealt well with inlined functions and
accessing their variables (internal RH#694824) after the Tom's fix:
	FYI: bug fix in gdb.Frame.block
	http://sourceware.org/ml/gdb-patches/2011-01/msg00133.html

The real fix is in fact only the frapy_read_var part.

frapy_block part generalizes it, I find it still doc/ compliant.

The gdbpy_lookup_symbol fix is obvious but it has no new testcase.

There is still gdbpy_block_for_pc (unaffected by this patch at all) which
works as described but it may be confusing as it does not behave well with
inlined functions when used as is.

Some comments are welcome.

No regressions on {x86_64,x86_64-m32,i686}-fedora15-linux-gnu.
The new testcase has been tested also on
{ppc64-m64,ppc64-m32}-rhel61-linux-gnu.


Thanks,
Jan


gdb/
2011-04-10  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix Python access to inlined frames.
	* python/py-frame.c (frapy_block): Remove variable fn_block.  Remove
	the code searching for the next function.  Find the objfile using
	lookup_objfile_from_block.
	(frapy_read_var): Find BLOCK using get_frame_block.
	* python/py-symbol.c (gdbpy_lookup_symbol): Likewise.

gdb/testsuite/
2011-04-10  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix Python access to inlined frames.
	* gdb.python/py-frame-inline.c: New file.
	* gdb.python/py-frame-inline.exp: New file.

--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -211,7 +211,7 @@ static PyObject *
 frapy_block (PyObject *self, PyObject *args)
 {
   struct frame_info *frame;
-  struct block *block = NULL, *fn_block;
+  struct block *block = NULL;
   volatile struct gdb_exception except;
 
   TRY_CATCH (except, RETURN_MASK_ALL)
@@ -221,27 +221,14 @@ frapy_block (PyObject *self, PyObject *args)
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
-  for (fn_block = block;
-       fn_block != NULL && BLOCK_FUNCTION (fn_block) == NULL;
-       fn_block = BLOCK_SUPERBLOCK (fn_block))
-    ;
-
-  if (block == NULL || fn_block == NULL || BLOCK_FUNCTION (fn_block) == NULL)
+  if (block == NULL)
     {
       PyErr_SetString (PyExc_RuntimeError,
 		       _("Cannot locate object file for block."));
       return NULL;
     }
 
-  if (block)
-    {
-      struct symtab *symt;
-
-      symt = SYMBOL_SYMTAB (BLOCK_FUNCTION (fn_block));
-      return block_to_block_object (block, symt->objfile);
-    }
-
-  Py_RETURN_NONE;
+  return block_to_block_object (block, lookup_objfile_from_block (block));
 }
 
 
@@ -436,7 +423,7 @@ frapy_read_var (PyObject *self, PyObject *args)
 	  FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
 
 	  if (!block)
-	    block = block_for_pc (get_frame_address_in_block (frame));
+	    block = get_frame_block (frame, NULL);
 	  var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
 	}
       GDB_PY_HANDLE_EXCEPTION (except);
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -275,8 +275,8 @@ gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
 
       TRY_CATCH (except, RETURN_MASK_ALL)
 	{
-	  selected_frame  = get_selected_frame (_("No frame selected."));
-	  block = block_for_pc (get_frame_address_in_block (selected_frame));
+	  selected_frame = get_selected_frame (_("No frame selected."));
+	  block = get_frame_block (selected_frame, NULL);
 	}
       GDB_PY_HANDLE_EXCEPTION (except);
     }
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-frame-inline.c
@@ -0,0 +1,43 @@
+/* This test is part of GDB, the GNU debugger.
+
+   Copyright 2011 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/>.  */
+
+volatile int v = 42;
+
+__attribute__((__always_inline__)) static int
+f (void)
+{
+  /* Provide first stub line so that GDB understand the PC is already inside
+     the inlined function and does not expect a step into it.  */
+  v++;
+  v++;		/* break-here */
+
+  return v;
+}
+
+__attribute__((__noinline__)) static int
+g (void)
+{
+  volatile int l = v;
+
+  return f ();
+}
+
+int
+main (void)
+{
+  return g ();
+}
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-frame-inline.exp
@@ -0,0 +1,39 @@
+# Copyright (C) 2011 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 gdb-python.exp
+
+set testfile "py-frame-inline"
+set srcfile ${testfile}.c
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+if ![runto main] then {
+    fail "Can't run to function f"
+    return 0
+}
+
+gdb_breakpoint [gdb_get_line_number "break-here"]
+gdb_continue_to_breakpoint "Block break here."
+
+gdb_test "info frame" "inlined into frame 1\r\n.*"
+
+gdb_test "up" "#1  g .*"
+
+gdb_test "python print gdb.selected_frame().read_var('l')" "\r\n42"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]