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.
This commit is contained in:
parent
64e7d9dddc
commit
f0823d2ce8
10 changed files with 137 additions and 5 deletions
|
@ -1,3 +1,13 @@
|
||||||
|
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>
|
2012-02-07 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
PR python/13599:
|
PR python/13599:
|
||||||
|
|
5
gdb/NEWS
5
gdb/NEWS
|
@ -15,6 +15,11 @@
|
||||||
** gdb.Symbol now has a 'line' attribute, holding the line number in
|
** gdb.Symbol now has a 'line' attribute, holding the line number in
|
||||||
the source at which the symbol was defined.
|
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.
|
* GDBserver now supports stdio connections.
|
||||||
E.g. (gdb) target remote | ssh myhost gdbserver - hello
|
E.g. (gdb) target remote | ssh myhost gdbserver - hello
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
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>
|
2012-02-07 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* gdb.texinfo (Symbols In Python): Document Symbol.line.
|
* gdb.texinfo (Symbols In Python): Document Symbol.line.
|
||||||
|
|
|
@ -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.
|
@code{gdb} module and described later in this chapter.
|
||||||
@end defvar
|
@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
|
@defvar Symbol.is_argument
|
||||||
@code{True} if the symbol is an argument of a function.
|
@code{True} if the symbol is an argument of a function.
|
||||||
@end defvar
|
@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
|
All other @code{gdb.Symbol} methods will throw an exception if it is
|
||||||
invalid at the time the method is called.
|
invalid at the time the method is called.
|
||||||
@end defun
|
@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
|
@end table
|
||||||
|
|
||||||
The available domain categories in @code{gdb.Symbol} are represented
|
The available domain categories in @code{gdb.Symbol} are represented
|
||||||
|
|
|
@ -54,8 +54,6 @@ typedef struct {
|
||||||
error (_("Frame is invalid.")); \
|
error (_("Frame is invalid.")); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static PyTypeObject frame_object_type;
|
|
||||||
|
|
||||||
/* Returns the frame_info object corresponding to the given Python Frame
|
/* Returns the frame_info object corresponding to the given Python Frame
|
||||||
object. If the frame doesn't exist anymore (the frame id doesn't
|
object. If the frame doesn't exist anymore (the frame id doesn't
|
||||||
correspond to any frame in the inferior), returns NULL. */
|
correspond to any frame in the inferior), returns NULL. */
|
||||||
|
@ -663,7 +661,7 @@ Return the value of the variable in this frame." },
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyTypeObject frame_object_type = {
|
PyTypeObject frame_object_type = {
|
||||||
PyObject_HEAD_INIT (NULL)
|
PyObject_HEAD_INIT (NULL)
|
||||||
0, /* ob_size */
|
0, /* ob_size */
|
||||||
"gdb.Frame", /* tp_name */
|
"gdb.Frame", /* tp_name */
|
||||||
|
|
|
@ -183,6 +183,29 @@ sympy_is_variable (PyObject *self, void *closure)
|
||||||
|| class == LOC_OPTIMIZED_OUT));
|
|| 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.
|
/* Implementation of gdb.Symbol.line -> int.
|
||||||
Returns the line number at which the symbol was defined. */
|
Returns the line number at which the symbol was defined. */
|
||||||
|
|
||||||
|
@ -211,6 +234,53 @@ sympy_is_valid (PyObject *self, PyObject *args)
|
||||||
Py_RETURN_TRUE;
|
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
|
/* Given a symbol, and a symbol_object that has previously been
|
||||||
allocated and initialized, populate the symbol_object with the
|
allocated and initialized, populate the symbol_object with the
|
||||||
struct symbol data. Also, register the symbol_object life-cycle
|
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." },
|
"True if the symbol is a function or method." },
|
||||||
{ "is_variable", sympy_is_variable, NULL,
|
{ "is_variable", sympy_is_variable, NULL,
|
||||||
"True if the symbol is a variable." },
|
"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,
|
{ "line", sympy_line, NULL,
|
||||||
"The source line number at which the symbol was defined." },
|
"The source line number at which the symbol was defined." },
|
||||||
{ NULL } /* Sentinel */
|
{ NULL } /* Sentinel */
|
||||||
|
@ -482,6 +554,9 @@ static PyMethodDef symbol_object_methods[] = {
|
||||||
{ "is_valid", sympy_is_valid, METH_NOARGS,
|
{ "is_valid", sympy_is_valid, METH_NOARGS,
|
||||||
"is_valid () -> Boolean.\n\
|
"is_valid () -> Boolean.\n\
|
||||||
Return true if this symbol is valid, false if not." },
|
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 */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,7 @@ extern PyTypeObject event_object_type;
|
||||||
extern PyTypeObject events_object_type;
|
extern PyTypeObject events_object_type;
|
||||||
extern PyTypeObject stop_event_object_type;
|
extern PyTypeObject stop_event_object_type;
|
||||||
extern PyTypeObject breakpoint_object_type;
|
extern PyTypeObject breakpoint_object_type;
|
||||||
|
extern PyTypeObject frame_object_type;
|
||||||
|
|
||||||
typedef struct breakpoint_object
|
typedef struct breakpoint_object
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.c (qq): New global.
|
||||||
* gdb.python/py-symbol.exp: Add test for frame-less
|
* gdb.python/py-symbol.exp: Add test for frame-less
|
||||||
|
|
|
@ -35,7 +35,7 @@ class SimpleClass
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int qq; /* line of qq */
|
int qq = 72; /* line of qq */
|
||||||
|
|
||||||
int func (int arg)
|
int func (int arg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 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_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"]
|
set qq_line [gdb_get_line_number "line of qq"]
|
||||||
gdb_test "python print gdb.lookup_symbol('qq')\[0\].line" "$qq_line" \
|
gdb_test "python print gdb.lookup_symbol('qq')\[0\].line" "$qq_line" \
|
||||||
"print line number of qq"
|
"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 {
|
if ![runto_main] then {
|
||||||
fail "Can't run to main"
|
fail "Can't run to main"
|
||||||
return 0
|
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\].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\].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
|
# Test is_constant attribute
|
||||||
gdb_py_test_silent_cmd "python t = gdb.lookup_symbol(\"one\")" "Get variable a" 0
|
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"
|
gdb_test "python print t\[0\].is_variable" "False" "Test t.is_variable"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue