gdb/gdb-python-newbacktrace.patch

155 lines
5.3 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
--
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