From patchwork Thu Jan 5 23:51:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Terekhov, Mikhail via Gdb-patches" X-Patchwork-Id: 62768 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 F02FA3858433 for ; Thu, 5 Jan 2023 23:51:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F02FA3858433 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1672962718; bh=Uq1V18xGqBXynh3Z4XFNsf78G+3qsDqe2FlqkTbBy5s=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=rowi/tW/msR4SqwPq3jetPaYq3nPwQKKEFK6E1IiubVUEF0d6Oie2Imai9B8n1oRd LVUM3Pr/DmlYZ1vo0zHJjjFlIgysFpEQZJVrzPEKTJoldFqLHz1g6YAiHQPPeTCCXh sErfWfFazCzUlpBOVvPlIp9i3sgtlEDLO3qptNJg= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-oa1-x29.google.com (mail-oa1-x29.google.com [IPv6:2001:4860:4864:20::29]) by sourceware.org (Postfix) with ESMTPS id 57F3A3858C39 for ; Thu, 5 Jan 2023 23:51:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 57F3A3858C39 Received: by mail-oa1-x29.google.com with SMTP id 586e51a60fabf-142b72a728fso150356fac.9 for ; Thu, 05 Jan 2023 15:51:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=thread-index:content-language:content-transfer-encoding :mime-version:message-id:date:subject:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=Uq1V18xGqBXynh3Z4XFNsf78G+3qsDqe2FlqkTbBy5s=; b=b+9jju64bG8vBrzZrt/SjryWlsFrZuc7WQzv9r1c+v2puCMYTGjvORzcC2HMQ9MAdh yOZAdiDyKGifOqlEbqZtFUxA4v9lb6Xpz2F6c8yT+sawQCwKU1RnwZDGWD6Sd820k0qU gsRmHQOeM902yIbI2VA9TQtwlRgwmMCi/G24V/hEfwWDYPvAtNNkCNHW+wyMjRr9e4UE Z644JoqBOIEfZqbxvKIL4p6Neud6OwNtDWRuY9wQsDoSp6OgOiLq9QVPm/s+N4mjwkq4 DXiWJGK2jzSeNBMugqog3KwfEiaPXEMAHgogSCprQovS7dlv1+4MdMiB/+1O4/UgKADm 9Uag== X-Gm-Message-State: AFqh2kos2qQEDeB42isL7RoGO/RNUrgOCsMj6IqbRJjgBnDoHUV4Oswy XCJSWSyL9WFgJrP3Pz3uOEypCHv+PFdGzA== X-Google-Smtp-Source: AMrXdXu0R9ywaod90aPItIa4dRF24/ib0gTmWhuFTFBmGLEEnycDWqAaSkNnqizPtqh67ZsHYkIMkg== X-Received: by 2002:a05:6871:470c:b0:148:1f81:d14c with SMTP id py12-20020a056871470c00b001481f81d14cmr22319248oab.14.1672962691250; Thu, 05 Jan 2023 15:51:31 -0800 (PST) Received: from Diamond ([177.200.77.147]) by smtp.gmail.com with ESMTPSA id x42-20020a056870332a00b00148316f78fesm43199oae.2.2023.01.05.15.51.29 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Jan 2023 15:51:30 -0800 (PST) To: Subject: [PATCH 1/1] Add extra __repr__() implementations to the Python API Date: Thu, 5 Jan 2023 20:51:06 -0300 Message-ID: <5c5101d92160$a1bc4eb0$e534ec10$@gmail.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Content-Language: en-us Thread-Index: AdkhYJPNOmvRMUxoQc+PlweXSXijHQ== X-Spam-Status: No, score=-6.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_PASS, 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: "dark.ryu.550--- via Gdb-patches" From: "Terekhov, Mikhail via Gdb-patches" Reply-To: dark.ryu.550@gmail.com Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Only a few types in the Python API currently have __repr__() implementations. This patch adds a few more of them. specifically: it adds __repr__() implementations to gdb.Symbol, gdb.Architecture, gdb.Block, gdb.Breakpoint, and gdb.Type. This makes it easier to play around the GDB Python API in the Python interpreter session invoked with the 'pi' command in GDB, giving more easily accessible type information to users. One thing to note about this patch is that it makes use of u8 string literals, so as to make sure we meet python's expectations of strings passed to it using PyUnicode_FromFormat being encoded in utf8. This should remove the chance of odd compilation environments spitting out strings Python would consider invalid for the function we're calling. --- static PyObject * typy_str (PyObject *self) { @@ -1612,7 +1669,7 @@ PyTypeObject type_object_type = 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ - 0, /*tp_repr*/ + &typy_repr, /*tp_repr*/ &type_object_as_number, /*tp_as_number*/ 0, /*tp_as_sequence*/ &typy_mapping, /*tp_as_mapping*/ diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c index 93c86964f3e..0f7e5ae137c 100644 --- a/gdb/python/py-symbol.c +++ b/gdb/python/py-symbol.c @@ -375,6 +375,16 @@ sympy_dealloc (PyObject *obj) Py_TYPE (obj)->tp_free (obj); } +static PyObject * +sympy_repr (PyObject *self) +{ + struct symbol *symbol = NULL; + + SYMPY_REQUIRE_VALID (self, symbol); + + return PyUnicode_FromFormat("", symbol->print_name()); +} + /* Implementation of gdb.lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this) A tuple with 2 elements is always returned. The first is the symbol @@ -732,7 +742,7 @@ PyTypeObject symbol_object_type = { 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ - 0, /*tp_repr*/ + sympy_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c index cf0978560f9..e607edb565a 100644 --- a/gdb/python/py-arch.c +++ b/gdb/python/py-arch.c @@ -319,6 +319,19 @@ archpy_integer_type (PyObject *self, PyObject *args, PyObject *kw) return type_to_type_object (type); } +static PyObject * +archpy_repr (PyObject *self) +{ + struct gdbarch *gdbarch = NULL; + + ARCHPY_REQUIRE_VALID (self, gdbarch); + + return PyUnicode_FromFormat( + "", + (gdbarch_bfd_arch_info (gdbarch))->arch_name, + (gdbarch_bfd_arch_info (gdbarch))->printable_name); +} + /* Implementation of gdb.architecture_names(). Return a list of all the BFD architecture names that GDB understands. */ @@ -391,7 +404,7 @@ PyTypeObject arch_object_type = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - 0, /* tp_repr */ + archpy_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c index b9aea3aca69..abf2bae353d 100644 --- a/gdb/python/py-block.c +++ b/gdb/python/py-block.c @@ -23,6 +23,7 @@ #include "symtab.h" #include "python-internal.h" #include "objfiles.h" +#include struct block_object { PyObject_HEAD @@ -424,6 +425,30 @@ blpy_iter_is_valid (PyObject *self, PyObject *args) Py_RETURN_TRUE; } +static PyObject * +blpy_repr (PyObject *self) +{ + const struct block *block; + BLPY_REQUIRE_VALID(self, block); + + const auto name = block->function() ? block->function()->print_name() : ""; + + auto iter = block_iterator{}; + block_iterator_first(block, &iter); + + std::stringstream ss; + const struct symbol *symbol; + while ((symbol = block_iterator_next(&iter)) != NULL) + { + ss << std::endl; + ss << symbol->print_name() << ","; + } + if (!ss.str().empty()) + ss << std::endl; + + return PyUnicode_FromFormat("", name, ss.str().c_str()); +} + int gdbpy_initialize_blocks (void) { @@ -486,7 +511,7 @@ PyTypeObject block_object_type = { 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ - 0, /*tp_repr*/ + blpy_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ &block_object_as_mapping, /*tp_as_mapping*/ diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index de7b9f4266b..bc80b5eec0e 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -33,6 +33,7 @@ #include "location.h" #include "py-event.h" #include "linespec.h" +#include extern PyTypeObject breakpoint_location_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("breakpoint_location_object"); @@ -967,6 +968,20 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) return 0; } +static PyObject * +bppy_repr(PyObject *self) +{ + const struct gdbpy_breakpoint_object* bp = (struct gdbpy_breakpoint_object*) self; + BPPY_REQUIRE_VALID(bp); + + return PyUnicode_FromFormat( + "", + bp->number, + bp->bp->thread, + bp->bp->hit_count, + bp->bp->enable_count); +} + /* Append to LIST the breakpoint Python object associated to B. Return true on success. Return false on failure, with the Python error @@ -1389,7 +1404,7 @@ PyTypeObject breakpoint_object_type = 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ - 0, /*tp_repr*/ + bppy_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ @@ -1604,6 +1619,31 @@ bplocpy_dealloc (PyObject *py_self) Py_TYPE (py_self)->tp_free (py_self); } +static PyObject * +bplocpy_repr (PyObject *py_self) +{ + auto *self = (gdbpy_breakpoint_location_object *) py_self; + BPPY_REQUIRE_VALID (self->owner); + BPLOCPY_REQUIRE_VALID (self->owner, self); + + const auto enabled = self->bp_loc->enabled ? u8"enabled " : u8"disabled "; + + std::stringstream ss; + ss << std::endl << enabled << std::endl; + ss << u8"requested_address=" << self->bp_loc->requested_address << u8" "; + ss << u8"actual_address=" << self->bp_loc->address << u8" " << std::endl; + if (self->bp_loc->symtab) + { + ss << u8"file=" << self->bp_loc->symtab->filename << u8":" << self->bp_loc->line_number << u8"" << std::endl; + } + + const auto fn_name = self->bp_loc->function_name.get (); + if (fn_name != nullptr) + ss << "in "<< fn_name << " " << std::endl; + + return PyUnicode_FromFormat("", ss.str().c_str()); +} + /* Attribute get/set Python definitions. */ static gdb_PyGetSetDef bp_location_object_getset[] = { @@ -1635,7 +1675,7 @@ PyTypeObject breakpoint_location_object_type = 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ - 0, /*tp_repr*/ + bplocpy_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 928efacfe8a..01095c16eef 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -442,6 +442,7 @@ typy_is_signed (PyObject *self, void *closure) Py_RETURN_TRUE; } + /* Return the type, stripped of typedefs. */ static PyObject * typy_strip_typedefs (PyObject *self, PyObject *args) @@ -1026,6 +1027,62 @@ typy_template_argument (PyObject *self, PyObject *args) return value_to_value_object (val); } +static PyObject * +typy_repr (PyObject *self) +{ + auto type = type_object_to_type (self); + + std::string kind; + switch(type->code()) + { + case TYPE_CODE_INT: kind = u8"integer"; break; + case TYPE_CODE_PTR: kind = u8"pointer"; break; + case TYPE_CODE_ARRAY: kind = u8"array"; break; + case TYPE_CODE_STRUCT: kind = u8"struct"; break; + case TYPE_CODE_UNION: kind = u8"union"; break; + case TYPE_CODE_ENUM: kind = u8"enum"; break; + case TYPE_CODE_FLAGS: kind = u8"bitflags"; break; + case TYPE_CODE_FUNC: kind = u8"function"; break; + case TYPE_CODE_FLT: kind = u8"float"; break; + case TYPE_CODE_VOID: kind = u8"void"; break; + case TYPE_CODE_SET: kind = u8"set"; break; + case TYPE_CODE_RANGE: kind = u8"range"; break; + case TYPE_CODE_STRING: kind = u8"string"; break; + case TYPE_CODE_ERROR: kind = u8""; break; + case TYPE_CODE_METHOD: kind = u8"method"; break; + case TYPE_CODE_METHODPTR: kind = u8"method pointer"; break; + case TYPE_CODE_MEMBERPTR: kind = u8"member value pointer"; break; + case TYPE_CODE_RVALUE_REF: kind = u8"rvalue reference"; break; + case TYPE_CODE_CHAR: kind = u8"character"; break; + case TYPE_CODE_BOOL: kind = u8"boolean"; break; + case TYPE_CODE_COMPLEX: kind = u8"complex"; break; + case TYPE_CODE_TYPEDEF: kind = u8"typedef"; break; + case TYPE_CODE_NAMESPACE: kind = u8"namespace"; break; + case TYPE_CODE_DECFLOAT: kind = u8"decimal float"; break; + case TYPE_CODE_MODULE: kind = u8"module"; break; + case TYPE_CODE_INTERNAL_FUNCTION: kind = u8"internal function"; break; + case TYPE_CODE_XMETHOD: kind = u8"cross method"; break; + case TYPE_CODE_FIXED_POINT: kind = u8"fixed point"; break; + case TYPE_CODE_NAMELIST: kind = u8"namelist"; break; + } + + string_file type_name; + try + { + current_language->print_type (type, "", + &type_name, -1, 0, + &type_print_raw_options); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + auto py_typename = PyUnicode_Decode (type_name.c_str (), type_name.size (), + host_charset (), NULL); + + return PyUnicode_FromFormat("", kind.c_str(), py_typename); +} +