154 lines
5.8 KiB
Diff
154 lines
5.8 KiB
Diff
http://sourceware.org/ml/archer/2011-q1/msg00024.html
|
||
Subject: [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
|
||
|
||
--
|
||
|
||
Index: gdb-7.2.50.20110305/gdb/doc/gdb.texinfo
|
||
===================================================================
|
||
--- gdb-7.2.50.20110305.orig/gdb/doc/gdb.texinfo 2011-03-05 08:27:09.000000000 +0100
|
||
+++ gdb-7.2.50.20110305/gdb/doc/gdb.texinfo 2011-03-05 08:28:33.000000000 +0100
|
||
@@ -22919,6 +22919,13 @@ The result is a @code{gdb.Symbol} object
|
||
is not found.
|
||
@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
|
||
Index: gdb-7.2.50.20110305/gdb/python/lib/gdb/FrameWrapper.py
|
||
===================================================================
|
||
--- gdb-7.2.50.20110305.orig/gdb/python/lib/gdb/FrameWrapper.py 2011-03-05 08:26:12.000000000 +0100
|
||
+++ gdb-7.2.50.20110305/gdb/python/lib/gdb/FrameWrapper.py 2011-03-05 08:27:22.000000000 +0100
|
||
@@ -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:
|
||
Index: gdb-7.2.50.20110305/gdb/python/py-symbol.c
|
||
===================================================================
|
||
--- gdb-7.2.50.20110305.orig/gdb/python/py-symbol.c 2011-02-26 03:07:09.000000000 +0100
|
||
+++ gdb-7.2.50.20110305/gdb/python/py-symbol.c 2011-03-05 08:27:22.000000000 +0100
|
||
@@ -167,6 +167,27 @@ sympy_is_variable (PyObject *self, void
|
||
|| 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
|
||
@@ -396,6 +417,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 },
|
||
@@ -449,7 +477,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 */
|
||
};
|
||
Index: gdb-7.2.50.20110305/gdb/testsuite/gdb.python/py-symbol.exp
|
||
===================================================================
|
||
--- gdb-7.2.50.20110305.orig/gdb/testsuite/gdb.python/py-symbol.exp 2011-02-22 23:48:12.000000000 +0100
|
||
+++ gdb-7.2.50.20110305/gdb/testsuite/gdb.python/py-symbol.exp 2011-03-05 08:27:22.000000000 +0100
|
||
@@ -76,6 +76,10 @@ gdb_test "python print 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
|