From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by sourceware.org (Postfix) with ESMTPS id 857F0385703F for ; Tue, 18 Jul 2023 11:57:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 857F0385703F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689681424; x=1721217424; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=usNwQ+zYFJ98R4xRO7ibyylv/ST5g1jOVPLRWsNSPSk=; b=PmaN5KnpCAItrRNZVBbDKhLgRVjcNJ+xHaz6jCqfklo+V7Kq1C2Q6uAz cNpoybZ8rfH4f04n9GM3f2zTnDNu0U1YFrIQINWt4P5cnDrXIji5ct4hn YWZUKYNngsRdpdW7weKG9KeOmf9Wb0/S8jcJWlHUDRPjx9XwGDPJCu/jv 2f9dxVEjbZBNv1bJpucsoxh5zepJ+7kTEkppbcf40voDdNXOVXkcqciu8 XARbehQT9YAmrwz967ueAz9YkN0frmsgMYSuQf0R+Ns8tp2I6V9a/yHQH TpsdaZfdEygrXrhjURxn1VActwExrcjsX+kw7PPgMB8PAwDwIk0401Erl w==; X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="363650493" X-IronPort-AV: E=Sophos;i="6.01,214,1684825200"; d="scan'208";a="363650493" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jul 2023 04:57:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10774"; a="837260844" X-IronPort-AV: E=Sophos;i="6.01,214,1684825200"; d="scan'208";a="837260844" Received: from unknown (HELO localhost) ([10.216.210.22]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jul 2023 04:57:03 -0700 From: Felix Willgerodt To: gdb-patches@sourceware.org, markus.t.metzger@intel.com, simark@simark.ca Subject: [PATCH v10 05/10] python: Introduce gdb.RecordAuxiliary class. Date: Tue, 18 Jul 2023 13:56:32 +0200 Message-Id: <20230718115637.3531-6-felix.willgerodt@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230718115637.3531-1-felix.willgerodt@intel.com> References: <20230718115637.3531-1-felix.willgerodt@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: 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. Reviewed-By: Eli Zaretskii --- gdb/doc/python.texi | 13 ++++++ gdb/python/py-record-btrace.c | 81 +++++++++++++++++++++++++++++------ gdb/python/py-record-btrace.h | 3 ++ gdb/python/py-record.c | 62 +++++++++++++++++++++++++-- gdb/python/py-record.h | 7 +++ 5 files changed, 150 insertions(+), 16 deletions(-) diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 9a342f34bf0..46d56464644 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -4106,6 +4106,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. @var{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 7978f3332c6..4a2a61e9b91 100644 --- a/gdb/python/py-record-btrace.c +++ b/gdb/python/py-record-btrace.c @@ -45,7 +45,8 @@ struct btpy_list_object { /* Stride size. */ Py_ssize_t step; - /* Either &BTPY_CALL_TYPE or &RECPY_INSN_TYPE. */ + /* Either &recpy_func_type, &recpy_insn_type, &recpy_aux_type or + &recpy_gap_type. */ PyTypeObject* element_type; }; @@ -141,15 +142,21 @@ 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; - btrace_find_insn_by_number (&iter, &tinfo->btrace, number); + if (btrace_find_insn_by_number (&iter, &tinfo->btrace, number) == 0) + { + PyErr_Format (gdbpy_gdb_error, _("No such instruction.")); + return nullptr; + } + err_code = btrace_insn_get_error (&iter); if (err_code != 0) @@ -163,6 +170,12 @@ 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 (tinfo, RECORD_METHOD_BTRACE, number); + return recpy_insn_new (tinfo, RECORD_METHOD_BTRACE, number); } @@ -424,6 +437,48 @@ recpy_bt_func_next (PyObject *self, void *closure) RECORD_METHOD_BTRACE, func->next); } +/* Implementation of Auxiliary.data [str] for btrace. */ + +PyObject * +recpy_bt_aux_data (PyObject *self, void *closure) +{ + const btrace_insn *insn; + const recpy_element_object *obj; + thread_info *tinfo; + btrace_insn_iterator iter; + + if (Py_TYPE (self) != &recpy_aux_type) + { + PyErr_Format (gdbpy_gdb_error, _("Must be a gdb.Auxiliary.")); + return NULL; + } + + obj = (const recpy_element_object *) self; + tinfo = obj->thread; + + if (tinfo == NULL || btrace_is_empty (tinfo)) + { + PyErr_Format (gdbpy_gdb_error, _("No such auxiliary object.")); + return NULL; + } + + if (btrace_find_insn_by_number (&iter, &tinfo->btrace, obj->number) == 0) + { + PyErr_Format (gdbpy_gdb_error, _("No such auxiliary object.")); + return NULL; + } + + insn = btrace_insn_get (&iter); + if (insn == NULL) + { + PyErr_Format (gdbpy_gdb_error, _("Not a valid auxiliary object.")); + return NULL; + } + + return PyUnicode_FromString + (iter.btinfo->aux_data.at (insn->aux_data_index).c_str ()); +} + /* Implementation of BtraceList.__len__ (self) -> int. */ static Py_ssize_t @@ -440,8 +495,9 @@ btpy_list_length (PyObject *self) } /* Implementation of - BtraceList.__getitem__ (self, key) -> BtraceInstruction and - BtraceList.__getitem__ (self, key) -> BtraceFunctionCall. */ + BtraceList.__getitem__ (self, key) -> BtraceInstruction, + BtraceList.__getitem__ (self, key) -> BtraceFunctionCall, + BtraceList.__getitem__ (self, key) -> BtraceAuxiliary. */ static PyObject * btpy_list_item (PyObject *self, Py_ssize_t index) @@ -455,10 +511,10 @@ 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); - else + if (obj->element_type == &recpy_func_type) return recpy_func_new (obj->thread, RECORD_METHOD_BTRACE, number); + else + return btpy_item_new (obj->thread, number); } /* Implementation of BtraceList.__getitem__ (self, slice) -> BtraceList. */ @@ -645,8 +701,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 @@ -668,7 +723,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 @@ -690,7 +745,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-btrace.h b/gdb/python/py-record-btrace.h index 0af8153b715..0ca3da8e86f 100644 --- a/gdb/python/py-record-btrace.h +++ b/gdb/python/py-record-btrace.h @@ -88,4 +88,7 @@ extern PyObject *recpy_bt_func_prev (PyObject *self, void *closure); /* Implementation of RecordFunctionSegment.next [RecordFunctionSegment]. */ extern PyObject *recpy_bt_func_next (PyObject *self, void *closure); +/* Implementation of RecordAuxiliary.decoded [str]. */ +extern PyObject *recpy_bt_aux_data (PyObject *self, void *closure); + #endif /* PYTHON_PY_RECORD_BTRACE_H */ diff --git a/gdb/python/py-record.c b/gdb/python/py-record.c index c96c649b29c..c093cdaf3d6 100644 --- a/gdb/python/py-record.c +++ b/gdb/python/py-record.c @@ -49,6 +49,12 @@ static PyTypeObject recpy_gap_type = { PyVarObject_HEAD_INIT (NULL, 0) }; +/* Python RecordAuxiliary type. */ + +PyTypeObject recpy_aux_type = { + PyVarObject_HEAD_INIT (nullptr, 0) +}; + /* Python RecordGap object. */ struct recpy_gap_object { @@ -390,8 +396,8 @@ recpy_element_hash (PyObject *self) return obj->number; } -/* Implementation of operator == and != of RecordInstruction and - RecordFunctionSegment. */ +/* Implementation of operator == and != of RecordInstruction, + RecordFunctionSegment and RecordAuxiliary. */ static PyObject * recpy_element_richcompare (PyObject *self, PyObject *other, int op) @@ -479,6 +485,38 @@ recpy_gap_reason_string (PyObject *self, void *closure) return PyUnicode_FromString (obj->reason_string); } +/* Create a new gdb.Auxiliary object. */ + +PyObject * +recpy_aux_new (thread_info *thread, enum record_method method, + Py_ssize_t number) +{ + recpy_element_object * const obj = PyObject_New (recpy_element_object, + &recpy_aux_type); + + if (obj == NULL) + return NULL; + + obj->thread = thread; + obj->method = method; + obj->number = number; + + return (PyObject *) obj; +} + +/* Implementation of Auxiliary.data [buffer]. */ + +static PyObject * +recpy_aux_data (PyObject *self, void *closure) +{ + const recpy_element_object * const obj = (recpy_element_object *) self; + + if (obj->method == RECORD_METHOD_BTRACE) + return recpy_bt_aux_data (self, closure); + + return PyErr_Format (PyExc_NotImplementedError, _("Not implemented.")); +} + /* Record method list. */ static PyMethodDef recpy_record_methods[] = { @@ -544,6 +582,14 @@ static gdb_PyGetSetDef recpy_gap_getset[] = { { NULL } }; +/* RecordAuxiliary member list. */ + +static gdb_PyGetSetDef recpy_aux_getset[] = { + { "number", recpy_element_number, nullptr, "element number", nullptr}, + { "data", recpy_aux_data, nullptr, "data", nullptr}, + { nullptr } +}; + /* Sets up the record API in the gdb module. */ static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION @@ -583,10 +629,20 @@ 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_element_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; + recpy_aux_type.tp_richcompare = recpy_element_richcompare; + recpy_aux_type.tp_hash = recpy_element_hash; + 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 6eec71e06e7..63e59798a02 100644 --- a/gdb/python/py-record.h +++ b/gdb/python/py-record.h @@ -59,6 +59,9 @@ extern PyTypeObject recpy_insn_type; /* Python RecordFunctionSegment type. */ extern PyTypeObject recpy_func_type; +/* Python RecordAuxiliary type. */ +extern PyTypeObject recpy_aux_type; + /* Create a new gdb.RecordInstruction object. */ extern PyObject *recpy_insn_new (thread_info *thread, enum record_method method, Py_ssize_t number); @@ -71,4 +74,8 @@ 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 (thread_info *thread, enum record_method method, + Py_ssize_t number); + #endif /* PYTHON_PY_RECORD_H */ -- 2.34.1 Intel Deutschland GmbH Registered Address: Am Campeon 10, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928