2010-02-28 Phil Muldoon <pmuldoon@redhat.com>
authorPhil Muldoon <pmuldoon@redhat.com>
Sun, 28 Feb 2010 21:56:50 +0000 (21:56 +0000)
committerPhil Muldoon <pmuldoon@redhat.com>
Sun, 28 Feb 2010 21:56:50 +0000 (21:56 +0000)
PR python/11036
* python/py-frame.c (frapy_read_var): Add block argument and logic
to cope with user provided blocks.

2010-02-28  Phil Muldoon  <pmuldoon@redhat.com>

* gdb.texinfo (Frames In Python): Add block parameter and
description to read_var text.

2010-02-28  Phil Muldoon  <pmuldoon@redhat.com>

* gdb.python/py-frame.exp: Add read_var block tests.
* gdb.python/py-frame.c (block): New function.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/python/py-frame.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-frame.c
gdb/testsuite/gdb.python/py-frame.exp

index 56f16d5..371b2f8 100644 (file)
@@ -1,3 +1,9 @@
+2010-02-28  Phil Muldoon  <pmuldoon@redhat.com>
+
+       PR python/11036
+       * python/py-frame.c (frapy_read_var): Add block argument and logic
+       to cope with user provided blocks.
+
 2010-02-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * infcall.c (call_function_by_hand): Remove gdb_assert on sp and old_sp.
index b92f634..078fdb9 100644 (file)
@@ -1,3 +1,8 @@
+2010-02-28  Phil Muldoon  <pmuldoon@redhat.com>
+
+       * gdb.texinfo (Frames In Python): Add block parameter and
+       description to read_var text.
+
 2010-02-26  Phil Muldoon  <pmuldoon@redhat.com>
             Tom Tromey  <tromey@redhat.com>
 
index f6105b7..460d0d5 100644 (file)
@@ -20799,9 +20799,13 @@ Return the frame's symtab and line object.
 @xref{Symbol Tables In Python}.
 @end defmethod
 
-@defmethod Frame read_var variable
-Return the value of the given variable in this frame.  @var{variable} must
-be a string.
+@defmethod Frame read_var variable @r{[}block@r{]}
+Return the value of @var{variable} in this frame.  If the optional
+argument @var{block} is provided, search for the variable from that
+block; otherwise start at the frame's current block (which is
+determined by the frame's current program counter).  @var{variable}
+must be a string or a @code{gdb.Symbol} object.  @var{block} must be a
+@code{gdb.Block} object.
 @end defmethod
 
 @defmethod Frame select
index 94211db..3b5320c 100644 (file)
@@ -380,20 +380,22 @@ frapy_find_sal (PyObject *self, PyObject *args)
   return sal_obj;
 }
 
-/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value.
-   Returns the value of the given variable in this frame.  The argument must be
-   a string.  Returns None if GDB can't find the specified variable.  */
-
+/* Implementation of gdb.Frame.read_var_value (self, variable,
+   [block]) -> gdb.Value.  If the optional block argument is provided
+   start the search from that block, otherwise search from the frame's
+   current block (determined by examining the resume address of the
+   frame).  The variable argument must be a string or an instance of a
+   gdb.Symbol.  The block argument must be an instance of gdb.Block.  */
 static PyObject *
 frapy_read_var (PyObject *self, PyObject *args)
 {
   struct frame_info *frame;
-  PyObject *sym_obj;
+  PyObject *sym_obj, *block_obj = NULL;
   struct symbol *var = NULL;   /* gcc-4.3.2 false warning.  */
   struct value *val = NULL;
   volatile struct gdb_exception except;
 
-  if (!PyArg_ParseTuple (args, "O", &sym_obj))
+  if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
     return NULL;
 
   if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
@@ -410,11 +412,23 @@ frapy_read_var (PyObject *self, PyObject *args)
        return NULL;
       cleanup = make_cleanup (xfree, var_name);
 
+      if (block_obj)
+       {
+         block = block_object_to_block (block_obj);
+         if (!block)
+           {
+             PyErr_SetString (PyExc_RuntimeError,
+                              _("Second argument must be block."));
+             return NULL;
+           }
+       }
+
       TRY_CATCH (except, RETURN_MASK_ALL)
        {
          FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
 
-         block = block_for_pc (get_frame_address_in_block (frame));
+         if (!block)
+           block = block_for_pc (get_frame_address_in_block (frame));
          var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
        }
       GDB_PY_HANDLE_EXCEPTION (except);
@@ -445,10 +459,15 @@ frapy_read_var (PyObject *self, PyObject *args)
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
-  if (val)
-    return value_to_value_object (val);
+  if (!val)
+    {
+      PyErr_Format (PyExc_ValueError,
+                   _("Variable cannot be found for symbol '%s'."),
+                   SYMBOL_NATURAL_NAME (var));
+      return NULL;
+    }
 
-  Py_RETURN_NONE;
+  return value_to_value_object (val);
 }
 
 /* Select this frame.  */
index 8684ebc..203aecb 100644 (file)
@@ -1,3 +1,8 @@
+2010-02-28  Phil Muldoon  <pmuldoon@redhat.com>
+
+       * gdb.python/py-frame.exp: Add read_var block tests.
+       * gdb.python/py-frame.c (block): New function.
+
 2010-02-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
            Daniel Jacobowitz  <dan@codesourcery.com>
 
index 22eb9f2..82db341 100644 (file)
@@ -8,7 +8,23 @@ int f1 (int a, int b)
   return f2(a) + b;
 }
 
+int block (void)
+{
+  int i = 99;
+  {
+    double i = 1.1;
+    double f = 2.2;
+    {
+      const char *i = "stuff";
+      const char *f = "foo";
+      const char *b = "bar";
+      return 0; /* Block break here.  */
+    }
+  }
+}
+
 int main (int argc, char *argv[])
 {
+  block ();
   return f1 (1, 2);
 }
index 6989207..150e737 100644 (file)
@@ -56,6 +56,30 @@ if ![runto_main] then {
     return 0
 }
 
+gdb_breakpoint [gdb_get_line_number "Block break here."]
+gdb_continue_to_breakpoint "Block break here."
+gdb_py_test_silent_cmd "python bf1 = gdb.selected_frame ()" "get frame" 0
+
+# First test that read_var is unaffected by PR 11036 changes.
+gdb_test "python print bf1.read_var(\"i\")" "\"stuff\"" "test i"
+gdb_test "python print bf1.read_var(\"f\")" "\"foo\"" "test f"
+gdb_test "python print bf1.read_var(\"b\")" "\"bar\"" "test b"
+
+# Test the read_var function in another block other than the current
+# block (in this case, the super block). Test thar read_var is reading
+# the correct variables of i and f but they are the correct value and type.
+gdb_py_test_silent_cmd "python sb = bf1.block().superblock" "get superblock" 0
+gdb_test "python print bf1.read_var(\"i\", sb)" "1.1.*" "test i = 1.1"
+gdb_test "python print bf1.read_var(\"i\", sb).type" "double" "test double i"
+gdb_test "python print bf1.read_var(\"f\", sb)" "2.2.*" "test f = 2.2"
+gdb_test "python print bf1.read_var(\"f\", sb).type" "double" "test double f"
+
+# And again test another outerblock, this time testing "i" is the
+# correct value and type.
+gdb_py_test_silent_cmd "python sb = sb.superblock" "get superblock" 0
+gdb_test "python print bf1.read_var(\"i\", sb)" "99" "test i = 99"
+gdb_test "python print bf1.read_var(\"i\", sb).type" "int" "test int i"
+
 gdb_breakpoint "f2"
 gdb_continue_to_breakpoint "breakpoint at f2"
 gdb_test "up" "" ""