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
7 changed files with 77 additions and 0 deletions
|
@ -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>
|
2014-09-03 James Hogan <james.hogan@imgtec.com>
|
||||||
|
|
||||||
* mips-linux-nat.c (mips_linux_read_description): Reset errno to 0
|
* 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
|
*** 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
|
* 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
|
for to the thread the signal was sent to, even if the user changed
|
||||||
threads before resuming. Previously GDB would often (but not
|
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>
|
2014-08-04 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* gdb.texinfo (Debugging Output): Update for change to "set debug
|
* 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}.
|
@xref{Symbol Tables In Python}.
|
||||||
@end defun
|
@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{]})
|
@defun Frame.read_var (variable @r{[}, block@r{]})
|
||||||
Return the value of @var{variable} in this frame. If the optional
|
Return the value of @var{variable} in this frame. If the optional
|
||||||
argument @var{block} is provided, search for the variable from that
|
argument @var{block} is provided, search for the variable from that
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "python-internal.h"
|
#include "python-internal.h"
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
|
#include "user-regs.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
@ -235,6 +236,40 @@ frapy_pc (PyObject *self, PyObject *args)
|
||||||
return gdb_py_long_from_ulongest (pc);
|
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.
|
/* Implementation of gdb.Frame.block (self) -> gdb.Block.
|
||||||
Returns the frame's code 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", frapy_pc, METH_NOARGS,
|
||||||
"pc () -> Long.\n\
|
"pc () -> Long.\n\
|
||||||
Return the frame's resume address." },
|
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", frapy_block, METH_NOARGS,
|
||||||
"block () -> gdb.Block.\n\
|
"block () -> gdb.Block.\n\
|
||||||
Return the frame's code block." },
|
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>
|
2014-09-03 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||||
|
|
||||||
PR python/16699
|
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' % 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"
|
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…
Add table
Add a link
Reference in a new issue