[PATCH 05/10] python: Introduce gdb.RecordAuxiliary class.

felix.willgerodt@intel.com felix.willgerodt@intel.com
Wed May 29 08:48:00 GMT 2019


From: Felix Willgerodt <felix.willgerodt@intel.com>

Auxiliary instructions are no real instructions and get their own object
class, similar to gaps. gdb.Record.instruction_history is now possibly a
list of gdb.RecordInstruction, gdb.RecordGap or gdb.RecordAuxiliary
objects.

This patch is in preparation for the new ptwrite feature, which is based on
auxiliary instructions.

2019-05-29  Felix Willgerodt  <felix.willgerodt@intel.com>

gdb/ChangeLog:
	* py-record-btrace.c (btpy_insn_or_gap_new): Removed.
	(btpy_item_new): New function.
	(btpy_list_item): Call btpy_item_new instead of recpy_insn_new.
	(recpy_bt_replay_position): Call btpy_item_new instead of
	btpy_insn_or_gap_new.
	(recpy_bt_begin): Call btpy_item_new instead of btpy_insn_or_gap_new.
	(recpy_bt_end): Call btpy_item_new instead of btpy_insn_or_gap_new.
	* py-record.c (recpy_aux_type): New static object.
	(recpy_aux_object): New typedef.
	(recpy_aux_new, recpy_aux_number, recpy_aux_data): New function.
	(recpy_aux_getset): New static object.
	(gdbpy_initialize_record): Initialize gdb.RecordAuxiliary type.

gdb/doc/ChangeLog:
	* python.texi (gdb.RecordAuxiliary): New documentation.

---
 gdb/doc/python.texi           | 13 +++++++
 gdb/python/py-record-btrace.c | 22 +++++++----
 gdb/python/py-record.c        | 73 ++++++++++++++++++++++++++++++++++-
 gdb/python/py-record.h        |  3 ++
 4 files changed, 103 insertions(+), 8 deletions(-)

diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 98e52bb770c..d4149f364e1 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -3495,6 +3495,19 @@ the current recording method.
 A human readable string with the reason for the gap.
 @end defvar
 
+Some @value{GDBN} features write auxiliary information into the execution
+history.  This information is represented by a @code{gdb.RecordAuxiliary} object
+in the instruction list.  It has the following attributes:
+
+@defvar RecordAuxiliary.number
+An integer identifying this auxiliary.  @code{number} corresponds to the numbers
+seen in @code{record instruction-history} (@pxref{Process Record and Replay}).
+@end defvar
+
+@defvar RecordAuxiliary.data
+A string representation of the auxiliary data.
+@end defvar
+
 A @code{gdb.RecordFunctionSegment} object has the following attributes:
 
 @defvar RecordFunctionSegment.number
diff --git a/gdb/python/py-record-btrace.c b/gdb/python/py-record-btrace.c
index e7153fb6d7b..81e43a00516 100644
--- a/gdb/python/py-record-btrace.c
+++ b/gdb/python/py-record-btrace.c
@@ -150,10 +150,11 @@ btrace_func_from_recpy_func (const PyObject * const pyobject)
 }
 
 /* Looks at the recorded item with the number NUMBER and create a
-   gdb.RecordInstruction or gdb.RecordGap object for it accordingly.  */
+   gdb.RecordInstruction, gdb.RecordGap or gdb.RecordAuxiliary object
+   for it accordingly.  */
 
 static PyObject *
-btpy_insn_or_gap_new (thread_info *tinfo, Py_ssize_t number)
+btpy_item_new (thread_info *tinfo, Py_ssize_t number)
 {
   btrace_insn_iterator iter;
   int err_code;
@@ -172,6 +173,14 @@ btpy_insn_or_gap_new (thread_info *tinfo, Py_ssize_t number)
       return recpy_gap_new (err_code, err_string, number);
     }
 
+  const struct btrace_insn *insn = btrace_insn_get (&iter);
+
+  gdb_assert (insn != nullptr);
+
+  if (insn->iclass == BTRACE_INSN_AUX)
+    return recpy_aux_new (iter.btinfo->aux_data[insn->aux_data_index].c_str (),
+			  number);
+
   return recpy_insn_new (tinfo, RECORD_METHOD_BTRACE, number);
 }
 
@@ -470,7 +479,7 @@ btpy_list_item (PyObject *self, Py_ssize_t index)
   number = obj->first + (obj->step * index);
 
   if (obj->element_type == &recpy_insn_type)
-    return recpy_insn_new (obj->thread, RECORD_METHOD_BTRACE, number);
+    return btpy_item_new (obj->thread, number);
   else
     return recpy_func_new (obj->thread, RECORD_METHOD_BTRACE, number);
 }
@@ -658,8 +667,7 @@ recpy_bt_replay_position (PyObject *self, void *closure)
   if (tinfo->btrace.replay == NULL)
     Py_RETURN_NONE;
 
-  return btpy_insn_or_gap_new (tinfo,
-			       btrace_insn_number (tinfo->btrace.replay));
+  return btpy_item_new (tinfo, btrace_insn_number (tinfo->btrace.replay));
 }
 
 /* Implementation of
@@ -681,7 +689,7 @@ recpy_bt_begin (PyObject *self, void *closure)
     Py_RETURN_NONE;
 
   btrace_insn_begin (&iterator, &tinfo->btrace);
-  return btpy_insn_or_gap_new (tinfo, btrace_insn_number (&iterator));
+  return btpy_item_new (tinfo, btrace_insn_number (&iterator));
 }
 
 /* Implementation of
@@ -703,7 +711,7 @@ recpy_bt_end (PyObject *self, void *closure)
     Py_RETURN_NONE;
 
   btrace_insn_end (&iterator, &tinfo->btrace);
-  return btpy_insn_or_gap_new (tinfo, btrace_insn_number (&iterator));
+  return btpy_item_new (tinfo, btrace_insn_number (&iterator));
 }
 
 /* Implementation of
diff --git a/gdb/python/py-record.c b/gdb/python/py-record.c
index d46a03e75ac..8b1b3c4e651 100644
--- a/gdb/python/py-record.c
+++ b/gdb/python/py-record.c
@@ -49,6 +49,12 @@ PyTypeObject recpy_gap_type = {
   PyVarObject_HEAD_INIT (NULL, 0)
 };
 
+/* Python RecordAuxiliary type.  */
+
+PyTypeObject recpy_aux_type = {
+  PyVarObject_HEAD_INIT (NULL, 0)
+};
+
 /* Python RecordGap object.  */
 typedef struct
 {
@@ -64,6 +70,18 @@ typedef struct
   Py_ssize_t number;
 } recpy_gap_object;
 
+/* Python RecordAuxiliary object.  */
+typedef struct
+{
+  PyObject_HEAD
+
+  /* Auxiliary data.  */
+  const char *data;
+
+  /* Element number.  */
+  Py_ssize_t number;
+} recpy_aux_object;
+
 /* Implementation of record.method.  */
 
 static PyObject *
@@ -477,6 +495,43 @@ recpy_gap_reason_string (PyObject *self, void *closure)
   return PyString_FromString (obj->reason_string);
 }
 
+/* Create a new gdb.Auxiliary object.  */
+
+PyObject *
+recpy_aux_new (const char *data, Py_ssize_t number)
+{
+  recpy_aux_object * const obj = PyObject_New (recpy_aux_object,
+					       &recpy_aux_type);
+
+  if (obj == NULL)
+   return NULL;
+
+  obj->data = data;
+  obj->number = number;
+
+  return (PyObject *) obj;
+}
+
+/* Implementation of Auxiliary.number [int].  */
+
+static PyObject *
+recpy_aux_number (PyObject *self, void *closure)
+{
+  const recpy_aux_object * const obj = (const recpy_aux_object *) self;
+
+  return PyInt_FromSsize_t (obj->number);
+}
+
+/* Implementation of Auxiliary.data [str].  */
+
+static PyObject *
+recpy_aux_data (PyObject *self, void *closure)
+{
+  const recpy_aux_object * const obj = (const recpy_aux_object *) self;
+
+  return PyString_FromString (obj->data);
+}
+
 /* Record method list.  */
 
 static PyMethodDef recpy_record_methods[] = {
@@ -542,6 +597,14 @@ static gdb_PyGetSetDef recpy_gap_getset[] = {
   { NULL }
 };
 
+/* RecordAuxiliary member list.  */
+
+static gdb_PyGetSetDef recpy_aux_getset[] = {
+  { "number", recpy_aux_number, NULL, "element number", NULL},
+  { "data", recpy_aux_data, NULL, "data", NULL},
+  { NULL }
+};
+
 /* Sets up the record API in the gdb module.  */
 
 int
@@ -581,10 +644,18 @@ gdbpy_initialize_record (void)
   recpy_gap_type.tp_doc = "GDB recorded gap object";
   recpy_gap_type.tp_getset = recpy_gap_getset;
 
+  recpy_aux_type.tp_new = PyType_GenericNew;
+  recpy_aux_type.tp_flags = Py_TPFLAGS_DEFAULT;
+  recpy_aux_type.tp_basicsize = sizeof (recpy_aux_object);
+  recpy_aux_type.tp_name = "gdb.RecordAuxiliary";
+  recpy_aux_type.tp_doc = "GDB recorded auxiliary object";
+  recpy_aux_type.tp_getset = recpy_aux_getset;
+
   if (PyType_Ready (&recpy_record_type) < 0
       || PyType_Ready (&recpy_insn_type) < 0
       || PyType_Ready (&recpy_func_type) < 0
-      || PyType_Ready (&recpy_gap_type) < 0)
+      || PyType_Ready (&recpy_gap_type) < 0
+      || PyType_Ready (&recpy_aux_type) < 0)
     return -1;
   else
     return 0;
diff --git a/gdb/python/py-record.h b/gdb/python/py-record.h
index 74da1bdc4d6..6e0ff23ad37 100644
--- a/gdb/python/py-record.h
+++ b/gdb/python/py-record.h
@@ -71,4 +71,7 @@ extern PyObject *recpy_func_new (thread_info *thread, enum record_method method,
 extern PyObject *recpy_gap_new (int reason_code, const char *reason_string,
 				Py_ssize_t number);
 
+/* Create a new gdb.RecordGap object.  */
+extern PyObject *recpy_aux_new (const char *data, Py_ssize_t number);
+
 #endif /* PYTHON_PY_RECORD_H */
-- 
2.20.1



More information about the Gdb-patches mailing list