aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2012-02-07 19:47:16 +0000
committerTom Tromey <tromey@redhat.com>2012-02-07 19:47:16 +0000
commitf0823d2ce8e4cb8b64176872a372d8147804fb10 (patch)
treefb7552f824929309c2b65a6b54b656e90066885a
parent64e7d9dddc00228cdbcecdd4c053cf83cf6608b7 (diff)
downloadgdb-f0823d2ce8e4cb8b64176872a372d8147804fb10.zip
gdb-f0823d2ce8e4cb8b64176872a372d8147804fb10.tar.gz
gdb-f0823d2ce8e4cb8b64176872a372d8147804fb10.tar.bz2
PR python/12027:
* python/python-internal.h (frame_object_type): Declare. * python/py-symbol.c (sympy_needs_frame): New function. (sympy_value): New function. (symbol_object_getset): Add "needs_frame". (symbol_object_methods): Add "value". * python/py-frame.c (frame_object_type): No longer static. gdb/doc * gdb.texinfo (Symbols In Python): Document Symbol.needs_frame and Symbol.value. gdb/testsuite * gdb.python/py-symbol.exp: Test Symbol.needs_frame and Symbol.value. * gdb.python/py-symbol.c (qq): Set default value.
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/NEWS5
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/gdb.texinfo14
-rw-r--r--gdb/python/py-frame.c4
-rw-r--r--gdb/python/py-symbol.c75
-rw-r--r--gdb/python/python-internal.h1
-rw-r--r--gdb/testsuite/ChangeLog8
-rw-r--r--gdb/testsuite/gdb.python/py-symbol.c2
-rw-r--r--gdb/testsuite/gdb.python/py-symbol.exp18
10 files changed, 137 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bc8b7d4..60c5833 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
2012-02-07 Tom Tromey <tromey@redhat.com>
+ PR python/12027:
+ * python/python-internal.h (frame_object_type): Declare.
+ * python/py-symbol.c (sympy_needs_frame): New function.
+ (sympy_value): New function.
+ (symbol_object_getset): Add "needs_frame".
+ (symbol_object_methods): Add "value".
+ * python/py-frame.c (frame_object_type): No longer static.
+
+2012-02-07 Tom Tromey <tromey@redhat.com>
+
PR python/13599:
* python/py-symbol.c (sympy_line): New function.
(symbol_object_getset): Add "line".
diff --git a/gdb/NEWS b/gdb/NEWS
index bb9429f..46ef6d8 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -15,6 +15,11 @@
** gdb.Symbol now has a 'line' attribute, holding the line number in
the source at which the symbol was defined.
+ ** gdb.Symbol now has the new attribute 'needs_frame' and the new
+ method 'value'. The former indicates whether the symbol needs a
+ frame in order to compute its value, and the latter computes the
+ symbol's value.
+
* GDBserver now supports stdio connections.
E.g. (gdb) target remote | ssh myhost gdbserver - hello
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 8dd113e..19b61be 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,5 +1,10 @@
2012-02-07 Tom Tromey <tromey@redhat.com>
+ * gdb.texinfo (Symbols In Python): Document Symbol.needs_frame and
+ Symbol.value.
+
+2012-02-07 Tom Tromey <tromey@redhat.com>
+
* gdb.texinfo (Symbols In Python): Document Symbol.line.
2012-01-27 Thomas Schwinge <thomas@codesourcery.com>
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 052820b..02beed7 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -23993,6 +23993,11 @@ of a symbol. Each address class is a constant defined in the
@code{gdb} module and described later in this chapter.
@end defvar
+@defvar Symbol.needs_frame
+This is @code{True} if evaluating this symbol's value requires a frame
+(@pxref{Frames In Python}) and @code{False} otherwise. Typically,
+local variables will require a frame, but other symbols will not.
+
@defvar Symbol.is_argument
@code{True} if the symbol is an argument of a function.
@end defvar
@@ -24020,6 +24025,15 @@ the symbol it refers to does not exist in @value{GDBN} any longer.
All other @code{gdb.Symbol} methods will throw an exception if it is
invalid at the time the method is called.
@end defun
+
+@defun Symbol.value (@r{[}frame@r{]})
+Compute the value of the symbol, as a @code{gdb.Value}. For
+functions, this computes the address of the function, cast to the
+appropriate type. If the symbol requires a frame in order to compute
+its value, then @var{frame} must be given. If @var{frame} is not
+given, or if @var{frame} is invalid, then this method will throw an
+exception.
+@end defun
@end table
The available domain categories in @code{gdb.Symbol} are represented
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 12cedc3..12a54e8 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -54,8 +54,6 @@ typedef struct {
error (_("Frame is invalid.")); \
} while (0)
-static PyTypeObject frame_object_type;
-
/* Returns the frame_info object corresponding to the given Python Frame
object. If the frame doesn't exist anymore (the frame id doesn't
correspond to any frame in the inferior), returns NULL. */
@@ -663,7 +661,7 @@ Return the value of the variable in this frame." },
{NULL} /* Sentinel */
};
-static PyTypeObject frame_object_type = {
+PyTypeObject frame_object_type = {
PyObject_HEAD_INIT (NULL)
0, /* ob_size */
"gdb.Frame", /* tp_name */
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index d44014c..1c00b48 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -183,6 +183,29 @@ sympy_is_variable (PyObject *self, void *closure)
|| class == LOC_OPTIMIZED_OUT));
}
+/* Implementation of gdb.Symbol.needs_frame -> Boolean.
+ Returns true iff the symbol needs a frame for evaluation. */
+
+static PyObject *
+sympy_needs_frame (PyObject *self, void *closure)
+{
+ struct symbol *symbol = NULL;
+ volatile struct gdb_exception except;
+ int result = 0;
+
+ SYMPY_REQUIRE_VALID (self, symbol);
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ result = symbol_read_needs_frame (symbol);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ if (result)
+ Py_RETURN_TRUE;
+ Py_RETURN_FALSE;
+}
+
/* Implementation of gdb.Symbol.line -> int.
Returns the line number at which the symbol was defined. */
@@ -211,6 +234,53 @@ sympy_is_valid (PyObject *self, PyObject *args)
Py_RETURN_TRUE;
}
+/* Implementation of gdb.Symbol.value (self[, frame]) -> gdb.Value. Returns
+ the value of the symbol, or an error in various circumstances. */
+
+static PyObject *
+sympy_value (PyObject *self, PyObject *args)
+{
+ struct symbol *symbol = NULL;
+ struct frame_info *frame_info = NULL;
+ PyObject *frame_obj = NULL;
+ struct value *value = NULL;
+ volatile struct gdb_exception except;
+
+ if (!PyArg_ParseTuple (args, "|O", &frame_obj))
+ return NULL;
+
+ if (frame_obj != NULL && !PyObject_TypeCheck (frame_obj, &frame_object_type))
+ {
+ PyErr_SetString (PyExc_TypeError, "argument is not a frame");
+ return NULL;
+ }
+
+ SYMPY_REQUIRE_VALID (self, symbol);
+ if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF)
+ {
+ PyErr_SetString (PyExc_TypeError, "cannot get the value of a typedef");
+ return NULL;
+ }
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ if (frame_obj != NULL)
+ {
+ frame_info = frame_object_to_frame_info (frame_obj);
+ if (frame_info == NULL)
+ error ("invalid frame");
+ }
+
+ if (symbol_read_needs_frame (symbol) && frame_info == NULL)
+ error ("symbol requires a frame to compute its value");
+
+ value = read_var_value (symbol, frame_info);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return value_to_value_object (value);
+}
+
/* 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
@@ -473,6 +543,8 @@ to display demangled or mangled names.", NULL },
"True if the symbol is a function or method." },
{ "is_variable", sympy_is_variable, NULL,
"True if the symbol is a variable." },
+ { "needs_frame", sympy_needs_frame, NULL,
+ "True if the symbol requires a frame for evaluation." },
{ "line", sympy_line, NULL,
"The source line number at which the symbol was defined." },
{ NULL } /* Sentinel */
@@ -482,6 +554,9 @@ static PyMethodDef symbol_object_methods[] = {
{ "is_valid", sympy_is_valid, METH_NOARGS,
"is_valid () -> Boolean.\n\
Return true if this symbol is valid, false if not." },
+ { "value", sympy_value, METH_VARARGS,
+ "value ([frame]) -> gdb.Value\n\
+Return the value of the symbol." },
{NULL} /* Sentinel */
};
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 22e6b41..1d6247d 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -121,6 +121,7 @@ extern PyTypeObject event_object_type;
extern PyTypeObject events_object_type;
extern PyTypeObject stop_event_object_type;
extern PyTypeObject breakpoint_object_type;
+extern PyTypeObject frame_object_type;
typedef struct breakpoint_object
{
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 39a952c..4fd340c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,4 +1,10 @@
-2012-01-31 Tom Tromey <tromey@redhat.com>
+2012-02-07 Tom Tromey <tromey@redhat.com>
+
+ * gdb.python/py-symbol.exp: Test Symbol.needs_frame and
+ Symbol.value.
+ * gdb.python/py-symbol.c (qq): Set default value.
+
+2012-02-07 Tom Tromey <tromey@redhat.com>
* gdb.python/py-symbol.c (qq): New global.
* gdb.python/py-symbol.exp: Add test for frame-less
diff --git a/gdb/testsuite/gdb.python/py-symbol.c b/gdb/testsuite/gdb.python/py-symbol.c
index d29849b..4c1c26d 100644
--- a/gdb/testsuite/gdb.python/py-symbol.c
+++ b/gdb/testsuite/gdb.python/py-symbol.c
@@ -35,7 +35,7 @@ class SimpleClass
};
#endif
-int qq; /* line of qq */
+int qq = 72; /* line of qq */
int func (int arg)
{
diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp
index 154eb37..0f5eb3c 100644
--- a/gdb/testsuite/gdb.python/py-symbol.exp
+++ b/gdb/testsuite/gdb.python/py-symbol.exp
@@ -42,10 +42,20 @@ gdb_py_test_silent_cmd "python main_func = gdb.lookup_global_symbol(\"main\")" "
gdb_test "python print main_func.is_function" "True" "Test main_func.is_function"
gdb_test "python print gdb.lookup_global_symbol(\"junk\")" "None" "Test lookup_global_symbol(\"junk\")"
+gdb_test "python print gdb.lookup_symbol('main')\[0\].value()" "$hex .main." \
+ "print value of main"
+
set qq_line [gdb_get_line_number "line of qq"]
gdb_test "python print gdb.lookup_symbol('qq')\[0\].line" "$qq_line" \
"print line number of qq"
+gdb_test "python print gdb.lookup_symbol('qq')\[0\].value()" "72" \
+ "print value of qq"
+
+gdb_test "python print gdb.lookup_symbol('qq')\[0\].needs_frame" "False" \
+ "print whether qq needs a frame"
+
+
if ![runto_main] then {
fail "Can't run to main"
return 0
@@ -88,6 +98,14 @@ gdb_test "python print a\[0\].is_argument" "False" "Test a.is_argument"
gdb_test "python print a\[0\].is_function" "False" "Test a.is_function"
gdb_test "python print a\[0\].addr_class == gdb.SYMBOL_LOC_COMPUTED" "True" "Test a.addr_class"
+gdb_test "python print a\[0\].value()" \
+ "symbol requires a frame to compute its value.*"\
+ "try to print value of a without a frame"
+gdb_test "python print a\[0\].value(frame)" "0" \
+ "print value of a"
+gdb_test "python print a\[0\].needs_frame" "True" \
+ "print whether a needs a frame"
+
# Test is_constant attribute
gdb_py_test_silent_cmd "python t = gdb.lookup_symbol(\"one\")" "Get variable a" 0
gdb_test "python print t\[0\].is_variable" "False" "Test t.is_variable"