Add support for reading frame registers to Python API.
The ability to read registers is needed to use Frame Filter API to display the frames created by JIT compilers. gdb/ChangeLog: 2014-08-29 Sasha Smundak <asmundak@google.com> * python/py-frame.c (frapy_read_register): New function. gdb/doc/ChangeLog: 2014-08-26 Sasha Smundak <asmundak@google.com> * python.texi (Frames in Python): Add read_register description. gdb/testsuite/ChangeLog: 2014-08-26 Sasha Smundak <asmundak@google.com> * gdb.python/py-frame.exp: Test Frame.read_register.
This commit is contained in:
parent
ac740bc7a9
commit
5f3b99cfed
|
@ -1,3 +1,7 @@
|
|||
2014-09-03 Sasha Smundak <asmundak@google.com>
|
||||
|
||||
* python/py-frame.c (frapy_read_register): New function.
|
||||
|
||||
2014-09-03 James Hogan <james.hogan@imgtec.com>
|
||||
|
||||
* mips-linux-nat.c (mips_linux_read_description): Reset errno to 0
|
||||
|
|
3
gdb/NEWS
3
gdb/NEWS
|
@ -3,6 +3,9 @@
|
|||
|
||||
*** Changes since GDB 7.8
|
||||
|
||||
* Python Scripting
|
||||
You can now access frame registers from Python scripts.
|
||||
|
||||
* On resume, GDB now always passes the signal the program had stopped
|
||||
for to the thread the signal was sent to, even if the user changed
|
||||
threads before resuming. Previously GDB would often (but not
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2014-09-03 Sasha Smundak <asmundak@google.com>
|
||||
|
||||
* python.texi (Frames in Python): Add read_register description.
|
||||
|
||||
2014-08-04 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.texinfo (Debugging Output): Update for change to "set debug
|
||||
|
|
|
@ -3589,6 +3589,13 @@ Return the frame's symtab and line object.
|
|||
@xref{Symbol Tables In Python}.
|
||||
@end defun
|
||||
|
||||
@defun Frame.read_register (register)
|
||||
Return the value of @var{register} in this frame. The @var{register}
|
||||
argument must be a string (e.g., @code{'sp'} or @code{'rax'}).
|
||||
Returns a @code{Gdb.Value} object. Throws an exception if @var{register}
|
||||
does not exist.
|
||||
@end defun
|
||||
|
||||
@defun Frame.read_var (variable @r{[}, block@r{]})
|
||||
Return the value of @var{variable} in this frame. If the optional
|
||||
argument @var{block} is provided, search for the variable from that
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "python-internal.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
#include "user-regs.h"
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
@ -235,6 +236,40 @@ frapy_pc (PyObject *self, PyObject *args)
|
|||
return gdb_py_long_from_ulongest (pc);
|
||||
}
|
||||
|
||||
/* Implementation of gdb.Frame.read_register (self, register) -> gdb.Value.
|
||||
Returns the value of a register in this frame. */
|
||||
|
||||
static PyObject *
|
||||
frapy_read_register (PyObject *self, PyObject *args)
|
||||
{
|
||||
volatile struct gdb_exception except;
|
||||
const char *regnum_str;
|
||||
struct value *val = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple (args, "s", ®num_str))
|
||||
return NULL;
|
||||
|
||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
struct frame_info *frame;
|
||||
int regnum;
|
||||
|
||||
FRAPY_REQUIRE_VALID (self, frame);
|
||||
|
||||
regnum = user_reg_map_name_to_regnum (get_frame_arch (frame),
|
||||
regnum_str,
|
||||
strlen (regnum_str));
|
||||
if (regnum >= 0)
|
||||
val = value_of_register (regnum, frame);
|
||||
|
||||
if (val == NULL)
|
||||
PyErr_SetString (PyExc_ValueError, _("Unknown register."));
|
||||
}
|
||||
GDB_PY_HANDLE_EXCEPTION (except);
|
||||
|
||||
return val == NULL ? NULL : value_to_value_object (val);
|
||||
}
|
||||
|
||||
/* Implementation of gdb.Frame.block (self) -> gdb.Block.
|
||||
Returns the frame's code block. */
|
||||
|
||||
|
@ -674,6 +709,9 @@ Return the reason why it's not possible to find frames older than this." },
|
|||
{ "pc", frapy_pc, METH_NOARGS,
|
||||
"pc () -> Long.\n\
|
||||
Return the frame's resume address." },
|
||||
{ "read_register", frapy_read_register, METH_VARARGS,
|
||||
"read_register (register_name) -> gdb.Value\n\
|
||||
Return the value of the register in the frame." },
|
||||
{ "block", frapy_block, METH_NOARGS,
|
||||
"block () -> gdb.Block.\n\
|
||||
Return the frame's code block." },
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2014-09-03 Sasha Smundak <asmundak@google.com>
|
||||
|
||||
* gdb.python/py-frame.exp: Test Frame.read_register.
|
||||
|
||||
2014-09-03 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
|
||||
PR python/16699
|
||||
|
|
|
@ -94,3 +94,20 @@ gdb_test "python print ('result = %s' % f0.read_var ('variable_which_surely_does
|
|||
gdb_test "python print ('result = %s' % f0.read_var ('a'))" " = 1" "test Frame.read_var - success"
|
||||
|
||||
gdb_test "python print ('result = %s' % (gdb.selected_frame () == f1))" " = True" "test gdb.selected_frame"
|
||||
|
||||
# Can read SP register.
|
||||
gdb_test "python print ('result = %s' % (gdb.selected_frame ().read_register ('sp') == gdb.parse_and_eval ('\$sp')))" \
|
||||
" = True" \
|
||||
"test Frame.read_register(sp)"
|
||||
|
||||
# PC value obtained via read_register is as expected.
|
||||
gdb_test "python print ('result = %s' % (f0.read_register('pc') == f0.pc()))" \
|
||||
" = True" \
|
||||
"test Frame.read_register(pc)"
|
||||
|
||||
# On x86-64, PC is in $rip register.
|
||||
if {[istarget x86_64-*]} {
|
||||
gdb_test "python print ('result = %s' % (f0.read_register('pc') == f0.read_register('rip')))" \
|
||||
" = True" \
|
||||
"test Frame.read_register(rip)"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue