From patchwork Fri Oct 21 11:59:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Willgerodt, Felix" X-Patchwork-Id: 59279 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D21AF3852764 for ; Fri, 21 Oct 2022 12:04:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D21AF3852764 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1666353888; bh=epPf3C9kfxXOOBLt19zUMTzD5aMZ9yO6tWM78lbSGKA=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=BIG+SB3FmvJPI3tQ60VDIwSinIlVVQ/595RdOdqesdiGY8ponOsPNgDpXw9Ju0dA7 aVBRDBquqD1JMCOyR42PL61IJz3UmevSPqNgYVLqfBbupeUZwTSXvuuiibOdaX1LqI t2goePY6IK0rJ9uOCmAci7meVAtBl2Sp1BV/dqv4= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by sourceware.org (Postfix) with ESMTPS id 32687385E02E for ; Fri, 21 Oct 2022 12:02:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 32687385E02E X-IronPort-AV: E=McAfee;i="6500,9779,10506"; a="333562227" X-IronPort-AV: E=Sophos;i="5.95,200,1661842800"; d="scan'208";a="333562227" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2022 05:02:35 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10506"; a="693676905" X-IronPort-AV: E=Sophos;i="5.95,200,1661842800"; d="scan'208";a="693676905" Received: from mulvlfelix.iul.intel.com (HELO localhost) ([172.28.48.92]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2022 05:02:34 -0700 To: gdb-patches@sourceware.org, markus.t.metzger@intel.com Subject: [PATCH v7 05/10] python: Introduce gdb.RecordAuxiliary class. Date: Fri, 21 Oct 2022 13:59:42 +0200 Message-Id: <20221021115947.359223-6-felix.willgerodt@intel.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20221021115947.359223-1-felix.willgerodt@intel.com> References: <20221021115947.359223-1-felix.willgerodt@intel.com> MIME-Version: 1.0 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, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Felix Willgerodt via Gdb-patches From: "Willgerodt, Felix" Reply-To: Felix Willgerodt Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" 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. --- gdb/doc/python.texi | 13 +++++++ gdb/python/py-record-btrace.c | 35 +++++++++++------ gdb/python/py-record.c | 73 ++++++++++++++++++++++++++++++++++- gdb/python/py-record.h | 3 ++ 4 files changed, 111 insertions(+), 13 deletions(-) diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 2692211f388..8561bb6c8f1 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -3892,6 +3892,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 85401010f0a..1dab097335b 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,10 +142,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; @@ -163,6 +165,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.at (insn->aux_data_index).c_str (), number); + + return recpy_insn_new (tinfo, RECORD_METHOD_BTRACE, number); } @@ -441,8 +451,10 @@ 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) -> BtraceAuxilliary and + BtraceList.__getitem__ (self, key) -> BtraceGap. */ static PyObject * btpy_list_item (PyObject *self, Py_ssize_t index) @@ -456,10 +468,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. */ @@ -646,8 +658,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 @@ -669,7 +680,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 @@ -691,7 +702,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 fd5cfee84eb..a7e091f3770 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 { @@ -64,6 +70,18 @@ struct recpy_gap_object Py_ssize_t number; }; +/* 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 PyUnicode_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 == nullptr) + return nullptr; + + 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 gdb_py_object_from_longest (obj->number).release (); +} + +/* 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 PyUnicode_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, nullptr, "element number", nullptr}, + { "data", recpy_aux_data, nullptr, "data", nullptr}, + { nullptr } +}; + /* 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 2c8cfd6e4a5..d1d784e758e 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 */