aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSasha Smundak <asmundak@google.com>2014-09-03 16:34:47 -0700
committerDoug Evans <dje@google.com>2014-09-03 16:34:47 -0700
commit5f3b99cfed3803f0b099152f54aac7cb90a2b926 (patch)
tree3104a86b35b1492fbb64e676e822a8311344f125
parentac740bc7a9103a561329ebf7aa05ff31bcab2267 (diff)
downloadgdb-5f3b99cfed3803f0b099152f54aac7cb90a2b926.zip
gdb-5f3b99cfed3803f0b099152f54aac7cb90a2b926.tar.gz
gdb-5f3b99cfed3803f0b099152f54aac7cb90a2b926.tar.bz2
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.
-rw-r--r--gdb/ChangeLog4
-rw-r--r--gdb/NEWS3
-rw-r--r--gdb/doc/ChangeLog4
-rw-r--r--gdb/doc/python.texi7
-rw-r--r--gdb/python/py-frame.c38
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.python/py-frame.exp17
7 files changed, 77 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ad1a87b..7348bfb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/NEWS b/gdb/NEWS
index d603cf7..46c6a87 100644
--- a/gdb/NEWS
+++ b/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
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 2bf94bc..767a598 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -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
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 4688783..3cb6bf8 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -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
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 120e147..859d115 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -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", &regnum_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." },
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index d6db24b..10d27b3 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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
diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp
index 3517824..e47f340 100644
--- a/gdb/testsuite/gdb.python/py-frame.exp
+++ b/gdb/testsuite/gdb.python/py-frame.exp
@@ -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)"
+}