This is the mail archive of the archer@sourceware.org mailing list for the Archer 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 RH BZ 672235


Bug:

http://bugzilla.redhat.com/show_bug.cgi?id=672235

The latter half of this bug was caused by removing the value function
from gdb.Symbol.  This happened quite some time ago, so I am a little
surprised it took this long to surface.

The old Symbol.value function never returned anything except a gdb.Block
if the symbol happened to represent a function a block.  Anything else
raised an error.  Way back when, I removed this function as it was an
obvious stub, and it was superseded by frame.read_var() which is a more
accurate method of determining the value of a symbol.

Wind forward to today, and it turns out one of the unported
archer-tromey-python scripts we ship in Fedora relies on this (symbol ->
block) API.  I thought about ways of trying to fix this. I thought about
just changing FrameWrapper to just take a block instead of a symbol
representing a function.  But FrameWrapper has an API that we shipped.
I tried to find the block through the existing API, but that did not
work too well.  The gdb.Block method block_for_pc can return a block
from a pc but this just turned out to be expensive and convoluted.  I
eventually just elected to add a block() function to gdb.Symbol which,
if the symbol represented a method or a function, would return the block.
Yet I am still not entirely satisfied.  It seems weird to ask the user
to retrieve symbol value from frame.read_var for most symbols, but in
the case of a function or method, use block().  I tried to use read_var
for this, but it returns a gdb.Value, and I could not figure out a way to
transform a gdb.Value to a gdb.Block.

Before I submit this for upstream review I'd like to see if anyone has
any comments.

Cheers

Phil

--

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 161ac1f..55eca2a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -22718,6 +22718,13 @@ domain constant defined in the @code{gdb} module and described later
 in this chapter.
 @end defun
 
+A @code{gdb.Symbol} object has the following methods:
+
+@defmethod Symbol block
+Returns a @code{gdb.Block} object if the symbol is a function or a
+method.  @xref{Blocks In Python}.
+@end defmethod
+
 A @code{gdb.Symbol} object has the following attributes:
 
 @table @code
diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py
index b790a54..5d98b0f 100644
--- a/gdb/python/lib/gdb/FrameWrapper.py
+++ b/gdb/python/lib/gdb/FrameWrapper.py
@@ -46,7 +46,7 @@ class FrameWrapper:
             return
 
         first = True
-        block = func.value
+        block = func.block ()
 
         for sym in block:
             if sym.is_argument:
@@ -60,7 +60,7 @@ class FrameWrapper:
             return
 
         first = True
-        block = func.value
+        block = func.block ()
 
         for sym in block:
             if not sym.is_argument:
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index e072dc8..1dfe394 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -167,6 +167,27 @@ sympy_is_variable (PyObject *self, void *closure)
 			      || class == LOC_OPTIMIZED_OUT));
 }
 
+static PyObject *
+sympy_get_block (PyObject *self, PyObject *args)
+{
+  struct symbol *symbol = NULL;
+
+  SYMPY_REQUIRE_VALID (self, symbol);
+
+  if (SYMBOL_CLASS (symbol) == LOC_BLOCK)
+    {
+      struct symtab *symt = SYMBOL_SYMTAB (symbol);
+
+      return block_to_block_object (SYMBOL_BLOCK_VALUE (symbol),
+				    symt->objfile);
+    }
+  else
+    PyErr_SetString (PyExc_RuntimeError,
+		     _("Symbol is not a block class."));
+
+  return NULL;
+}
+
 /* Given a symbol, and a symbol_object that has previously been
    allocated and initialized, populate the symbol_object with the
    struct symbol data.  Also, register the symbol_object life-cycle
@@ -362,6 +383,13 @@ gdbpy_initialize_symbols (void)
 
 
 
+static PyMethodDef symbol_object_methods[] = {
+  { "block", sympy_get_block, METH_NOARGS,
+    "block () -> gdb.Block.\n\
+Return the block of this symbol, if the symbol represents a function." },
+  {NULL}  /* Sentinel */
+};
+
 static PyGetSetDef symbol_object_getset[] = {
   { "symtab", sympy_get_symtab, NULL,
     "Symbol table in which the symbol appears.", NULL },
@@ -415,7 +443,7 @@ PyTypeObject symbol_object_type = {
   0,				  /*tp_weaklistoffset */
   0,				  /*tp_iter */
   0,				  /*tp_iternext */
-  0,				  /*tp_methods */
+  symbol_object_methods,	  /*tp_methods */
   0,				  /*tp_members */
   symbol_object_getset		  /*tp_getset */
 };
diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp
index 8e3aec1..6d43566 100644
--- a/gdb/testsuite/gdb.python/py-symbol.exp
+++ b/gdb/testsuite/gdb.python/py-symbol.exp
@@ -69,6 +69,10 @@ gdb_test "python print func.print_name" "func" "Test func.print_name"
 gdb_test "python print func.linkage_name" "func" "Test func.linkage_name"
 gdb_test "python print func.addr_class == gdb.SYMBOL_LOC_BLOCK" "True" "Test func.addr_class"
 
+# Test block() method
+gdb_py_test_silent_cmd "python func = frame.block().function" "Get block" 0
+gdb_test "python print func.block().function.name" "func" "Test block method"
+
 gdb_breakpoint [gdb_get_line_number "Break at end."]
 gdb_continue_to_breakpoint "Break at end."
 gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0


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