From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ot1-x334.google.com (mail-ot1-x334.google.com [IPv6:2607:f8b0:4864:20::334]) by sourceware.org (Postfix) with ESMTPS id 1A3D53858434 for ; Thu, 18 May 2023 03:34:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1A3D53858434 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ot1-x334.google.com with SMTP id 46e09a7af769-6ab03bb1991so522930a34.0 for ; Wed, 17 May 2023 20:34:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1684380844; x=1686972844; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=/tVvn/DCIqqSFqIpPDgDHsN6rSzvCdWihcm5F0m91Yg=; b=c/WOOsSI/hQwZPzIYD3qWbO/PYOxVGIDHq0pDqQ+ABivslnvOlwkUiMlzNbcHYh0YC TiTxwpI63SCOO96izgrMOGA48StSchwn0x2OlTlTOEgQiPe83es1dXG0o9TggR7ULyOu dEZqHr97x4vo0zzLGAxEno1chpAMXoAcJ7YkQE3Dy7tpVz8Crz9VAX3l9jP//+algATW d/oC1NE4RiMrwvDvlubTmwAlUwPWJ1i0BD77pxnjGh90qD7nNtu//QMJQjU5Ku+VR+wQ yok3MpNnw4TwQkw7ruUKhQtyCBU5dDsCpJyrmDoyMqjGmkPAwy2Dh5s0XZS6cL4Qr8bR NSjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684380844; x=1686972844; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/tVvn/DCIqqSFqIpPDgDHsN6rSzvCdWihcm5F0m91Yg=; b=V2SbD6+SVgYxEa0afqlxAhEisTG8n17YyrGoSvuDVD+/hSifD0CLxBEig4LTSYpGDk c8VKdBZ5iP7zfMX82P8IUG8q0kxPjnPXDFxr9+2fTpVWmA58SzKg8VRnRYAOonvsPYsK FcEurXUi11PAoAWpNOyPA9MObAkC0xXaF/ju8eiAAIB8qClwVRfGG1TAqDNGHXrtw+zS yYp3R2a+eXjvn9utOmpEwB5VcIDs82ozOuwsbLddT1CQ1pvDQnNnNagZk7yctwmmmHC4 ZjMewGG0azgaTnCPEBIum/Y/ORDYpKne6bGiYSahjJ/RMZqKnGlao9sOJHyCO9HMzOwo RcHQ== X-Gm-Message-State: AC+VfDyWUAhBNezDFq5w6TabQPoHpm9p0eVuW3eqQWHQLrxeKgKH+S4Z kVd3RuoRLRnVhFJ/f9obLNTbP5yTQCtpBw== X-Google-Smtp-Source: ACHHUZ7uYvGnJ16CcvON8xGKWwGKdNkgsx7z7N4x4vtg399vHi20iZGRWffppWPZoLKvhUYkZ4LwBA== X-Received: by 2002:a05:6830:22cb:b0:6ac:8a16:63e9 with SMTP id q11-20020a05683022cb00b006ac8a1663e9mr326368otc.19.1684380844195; Wed, 17 May 2023 20:34:04 -0700 (PDT) Received: from localhost.localdomain ([177.200.70.140]) by smtp.gmail.com with ESMTPSA id s20-20020a9d7594000000b006aaf82bd5a2sm277147otk.43.2023.05.17.20.34.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 May 2023 20:34:03 -0700 (PDT) From: Matheus Branco Borella To: gdb-patches@sourceware.org Subject: [PATCH] Add __repr__() implementation to a few Python types Date: Thu, 18 May 2023 00:33:57 -0300 Message-Id: <20230518033357.77174-1-dark.ryu.550@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <87y1psc7pu.fsf@redhat.com> References: <87y1psc7pu.fsf@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.0 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,SPF_HELO_NONE,SPF_PASS,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: From: Matheus Branco Borella via 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 tipe information to users. An example of how this would look like: ``` (gdb) pi >> gdb.lookup_type("char") >> gdb.lookup_global_symbol("main") ``` Okay, this should have all of the changes suggested in the replies. Sorry it took me this long to get back to this. Life happened. I also made it so that no more than five symbols get written out by `gdb.Block`, showing how many were elided, if any. This should be a better compromise between expressiveness and clutter than the first implementation. This patch makes use of `type_allocator` for type initialization and of `block_iterator_range` for block symbol iteration. --- gdb/python/py-arch.c | 17 ++++- gdb/python/py-block.c | 47 +++++++++++++- gdb/python/py-breakpoint.c | 75 +++++++++++++++++++++- gdb/python/py-symbol.c | 17 ++++- gdb/python/py-type.c | 32 ++++++++- gdb/testsuite/gdb.python/py-arch.exp | 6 ++ gdb/testsuite/gdb.python/py-block.c | 28 ++++++++ gdb/testsuite/gdb.python/py-block.exp | 37 ++++++++++- gdb/testsuite/gdb.python/py-breakpoint.exp | 24 ++++--- gdb/testsuite/gdb.python/py-symbol.exp | 2 + gdb/testsuite/gdb.python/py-type.exp | 4 ++ 11 files changed, 270 insertions(+), 19 deletions(-) diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c index 4d133d1fe1..44df6db545 100644 --- a/gdb/python/py-arch.c +++ b/gdb/python/py-arch.c @@ -319,6 +319,21 @@ archpy_integer_type (PyObject *self, PyObject *args, PyObject *kw) return type_to_type_object (type); } +/* __repr__ implementation for gdb.Architecture. */ + +static PyObject * +archpy_repr (PyObject *self) +{ + const auto gdbarch = arch_object_to_gdbarch (self); + if (gdbarch == nullptr) + return PyUnicode_FromFormat ("<%s (invalid)>", Py_TYPE (self)->tp_name); + + return PyUnicode_FromFormat ("<%s arch_name=%s printable_name=%s>", + Py_TYPE (self)->tp_name, + 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. */ @@ -395,7 +410,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 09fa74d862..6bca88d2fb 100644 --- a/gdb/python/py-block.c +++ b/gdb/python/py-block.c @@ -418,6 +418,51 @@ blpy_iter_is_valid (PyObject *self, PyObject *args) Py_RETURN_TRUE; } +/* __repr__ implementation for gdb.Block. */ + +static PyObject * +blpy_repr (PyObject *self) +{ + const auto block = block_object_to_block (self); + if (block == nullptr) + return PyUnicode_FromFormat ("<%s (invalid)>", + Py_TYPE (self)->tp_name); + + const auto name = block->function () ? + block->function ()->print_name () : ""; + + std::string str; + unsigned int written_symbols = 0; + const int len = mdict_size (block->multidict ()); + for (struct symbol *symbol : block_iterator_range (block)) + { + if(++written_symbols >= 6) + { + const int remaining = len - 5; + if (remaining == 1) + { + str = (str + "\n ") + + string_printf("... (%d more symbol)", len - 5); + } + else + { + str = (str + "\n ") + + string_printf("... (%d more symbols)", len - 5); + } + + break; + } + str = (str + "\n ") + symbol->print_name (); + if (written_symbols < len) + str = str + ","; + } + if(!str.empty ()) + str += "\n"; + + return PyUnicode_FromFormat ("<%s %s {%s}>", Py_TYPE (self)->tp_name, + name, str.c_str ()); +} + static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION gdbpy_initialize_blocks (void) { @@ -482,7 +527,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 becb04c91c..1dd746ba94 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 "gdbsupport/common-utils.h" extern PyTypeObject breakpoint_location_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("breakpoint_location_object"); @@ -981,6 +982,32 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) return 0; } +/* __repr__ implementation for gdb.Breakpoint. */ + +static PyObject * +bppy_repr (PyObject *self) +{ + const auto bp = (struct gdbpy_breakpoint_object*) self; + if (bp->bp == nullptr) + return PyUnicode_FromFormat ("<%s (invalid)>", + Py_TYPE (self)->tp_name); + + std::string str = " "; + if (bp->bp->thread != -1) + str += string_printf ("thread=%d ", bp->bp->thread); + if (bp->bp->task > 0) + str += string_printf ("task=%d ", bp->bp->task); + if (bp->bp->enable_count > 0) + str += string_printf ("enable_count=%d ", + bp->bp->enable_count); + str.pop_back (); + + return PyUnicode_FromFormat ("<%s number=%d hits=%d%s>", + Py_TYPE (self)->tp_name, + bp->bp->number, bp->bp->hit_count, + str.c_str ()); +} + /* Append to LIST the breakpoint Python object associated to B. Return true on success. Return false on failure, with the Python error @@ -1406,7 +1433,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*/ @@ -1624,6 +1651,50 @@ bplocpy_dealloc (PyObject *py_self) Py_TYPE (py_self)->tp_free (py_self); } +/* __repr__ implementation for gdb.BreakpointLocation. */ + +static PyObject * +bplocpy_repr (PyObject *py_self) +{ + const auto self = (gdbpy_breakpoint_location_object *) py_self; + if (self->owner == nullptr || self->owner->bp == nullptr + || self->owner->bp != self->bp_loc->owner) + return PyUnicode_FromFormat ("<%s (invalid)>", + Py_TYPE (self)->tp_name); + + const auto enabled = self->bp_loc->enabled ? "enabled" : "disabled"; + + std::string str(enabled); + + str += " address=0x"; + str += string_printf + ("%s", core_addr_to_string_nz (self->bp_loc->address)); + + if (self->bp_loc->requested_address != self->bp_loc->address) + { + str += " requested_address=0x"; + str += string_printf + ("%s", core_addr_to_string_nz (self->bp_loc->requested_address)); + } + if (self->bp_loc->symtab != nullptr) + { + str += " source="; + str += self->bp_loc->symtab->filename; + str += ":"; + str += string_printf ("%d", self->bp_loc->line_number); + } + + const auto fn_name = self->bp_loc->function_name.get (); + if (fn_name != nullptr) + { + str += " in "; + str += fn_name; + } + + return PyUnicode_FromFormat ("<%s %s>", Py_TYPE (self)->tp_name, + str.c_str ()); +} + /* Attribute get/set Python definitions. */ static gdb_PyGetSetDef bp_location_object_getset[] = { @@ -1655,7 +1726,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-symbol.c b/gdb/python/py-symbol.c index ff3d18504e..6cf9825d7f 100644 --- a/gdb/python/py-symbol.c +++ b/gdb/python/py-symbol.c @@ -378,6 +378,21 @@ sympy_dealloc (PyObject *obj) Py_TYPE (obj)->tp_free (obj); } +/* __repr__ implementation for gdb.Symbol. */ + +static PyObject * +sympy_repr (PyObject *self) +{ + const auto symbol = symbol_object_to_symbol (self); + if (symbol == nullptr) + return PyUnicode_FromFormat ("<%s (invalid)>", + Py_TYPE (self)->tp_name); + + return PyUnicode_FromFormat ("<%s print_name=%s>", + Py_TYPE (self)->tp_name, + 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 @@ -741,7 +756,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-type.c b/gdb/python/py-type.c index b9fa741177..283d595546 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -1028,6 +1028,36 @@ typy_template_argument (PyObject *self, PyObject *args) return result; } +/* __repr__ implementation for gdb.Type. */ + +static PyObject * +typy_repr (PyObject *self) +{ + const auto type = type_object_to_type (self); + if (type == nullptr) + return PyUnicode_FromFormat ("<%s (invalid)>", + Py_TYPE (self)->tp_name); + + const char *code = pyty_codes[type->code ()].name; + 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 ("<%s code=%s name=%U>", + Py_TYPE (self)->tp_name, code, + py_typename); +} + static PyObject * typy_str (PyObject *self) { @@ -1617,7 +1647,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/testsuite/gdb.python/py-arch.exp b/gdb/testsuite/gdb.python/py-arch.exp index 4f4b4aa766..597943ff68 100644 --- a/gdb/testsuite/gdb.python/py-arch.exp +++ b/gdb/testsuite/gdb.python/py-arch.exp @@ -27,6 +27,8 @@ if ![runto_main] { # Test python/15461. Invalid architectures should not trigger an # internal GDB assert. gdb_py_test_silent_cmd "python empty = gdb.Architecture()" "get empty arch" 0 +gdb_test "python print(repr (empty))" "" \ + "Test empty achitecture __repr__ does not trigger an assert" gdb_test "python print(empty.name())" ".*Architecture is invalid.*" \ "Test empty architecture.name does not trigger an assert" gdb_test "python print(empty.disassemble())" ".*Architecture is invalid.*" \ @@ -44,6 +46,10 @@ gdb_py_test_silent_cmd "python insn_list3 = arch.disassemble(pc, count=1)" \ gdb_py_test_silent_cmd "python insn_list4 = arch.disassemble(gdb.Value(pc))" \ "disassemble no end no count" 0 +gdb_test "python print (repr (arch))" \ + "" \ + "test __repr__ for architecture" + gdb_test "python print (len(insn_list1))" "1" "test number of instructions 1" gdb_test "python print (len(insn_list2))" "1" "test number of instructions 2" gdb_test "python print (len(insn_list3))" "1" "test number of instructions 3" diff --git a/gdb/testsuite/gdb.python/py-block.c b/gdb/testsuite/gdb.python/py-block.c index a0c6e16560..7e26f2d1fe 100644 --- a/gdb/testsuite/gdb.python/py-block.c +++ b/gdb/testsuite/gdb.python/py-block.c @@ -30,9 +30,37 @@ int block_func (void) } } +int no_locals_func (void) +{ + return block_func (); +} + +int few_locals_func (void) +{ + int i = 0; + int j = 0; + int k = 0; + int x = 0; + int y = 0; + return block_func (); +} + +int many_locals_func (void) +{ + int i = 0; + int j = 0; + int k = 0; + int x = 0; + int y = 0; + int z = 0; + return block_func (); +} int main (int argc, char *argv[]) { block_func (); + no_locals_func (); + few_locals_func (); + many_locals_func (); return 0; /* Break at end. */ } diff --git a/gdb/testsuite/gdb.python/py-block.exp b/gdb/testsuite/gdb.python/py-block.exp index 3bdf97294a..dc2f2f53af 100644 --- a/gdb/testsuite/gdb.python/py-block.exp +++ b/gdb/testsuite/gdb.python/py-block.exp @@ -38,7 +38,7 @@ gdb_continue_to_breakpoint "Block break here." gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0 gdb_py_test_silent_cmd "python block = frame.block()" \ "Get block, initial innermost block" 0 -gdb_test "python print (block)" "" "check block not None" +gdb_test "python print (block)" " \{.*\}>" "check block not None" gdb_test "python print (block.function)" "None" "first anonymous block" gdb_test "python print (block.start)" "${decimal}" "check start not None" gdb_test "python print (block.end)" "${decimal}" "check end not None" @@ -68,15 +68,46 @@ gdb_test_no_output "python block = block.superblock" "get superblock 2" gdb_test "python print (block.function)" "block_func" \ "Print superblock 2 function" +# Switch frames, then test block for no_locals_func. +gdb_test "continue" ".*" "continue to no_locals_func breakpoint" +gdb_test "up" ".*" "up to no_locals_func" +gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame 2" 0 +gdb_py_test_silent_cmd "python block = frame.block()" "Get Frame 2's block" 0 +gdb_test "python print (repr (block))" "" \ + "Check block in no_locals_func" +gdb_test "python print (block.function)" "no_locals_func" \ + "no_locals_func block" + +# Switch frames, then test block for few_locals_func. +gdb_test "continue" ".*" "continue to few_locals_func breakpoint" +gdb_test "up" ".*" "up to few_locals_func" +gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame 2" 0 +gdb_py_test_silent_cmd "python block = frame.block()" "Get Frame 2's block" 0 +gdb_test "python print (repr (block))" \ + "" \ + "Check block in few_locals_func" +gdb_test "python print (block.function)" "few_locals_func" \ + "few_locals_func block" + +# Switch frames, then test block for many_locals_func. +gdb_test "continue" ".*" "continue to many_locals_func breakpoint" +gdb_test "up" ".*" "up to many_locals_func" +gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame 2" 0 +gdb_py_test_silent_cmd "python block = frame.block()" "Get Frame 2's block" 0 +gdb_test "python print (repr (block))" \ + "" \ + "Check block in many_locals_func" +gdb_test "python print (block.function)" "many_locals_func" \ + "many_locals_func block" + # Switch frames, then test for main block. gdb_test "up" ".*" gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame 2" 0 gdb_py_test_silent_cmd "python block = frame.block()" "Get Frame 2's block" 0 -gdb_test "python print (block)" "" \ +gdb_test "python print (repr (block))" "" \ "Check Frame 2's block not None" gdb_test "python print (block.function)" "main" "main block" - # Test Block is_valid. This must always be the last test in this # testcase as it unloads the object file. delete_breakpoints diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 76094c95d1..77e44f6e3c 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -51,11 +51,13 @@ proc_with_prefix test_bkpt_basic { } { return 0 } + set repr_pattern "" + # Now there should be one breakpoint: main. gdb_py_test_silent_cmd "python blist = gdb.breakpoints()" \ "Get Breakpoint List" 0 - gdb_test "python print (blist\[0\])" \ - "" "Check obj exists @main" + gdb_test "python print (repr (blist\[0\]))" \ + "$repr_pattern" "Check obj exists @main" gdb_test "python print (blist\[0\].location)" \ "main" "Check breakpoint location @main" gdb_test "python print (blist\[0\].pending)" "False" \ @@ -72,12 +74,12 @@ proc_with_prefix test_bkpt_basic { } { "Get Breakpoint List" 0 gdb_test "python print (len(blist))" \ "2" "Check for two breakpoints" - gdb_test "python print (blist\[0\])" \ - "" "Check obj exists @main 2" + gdb_test "python print (repr (blist\[0\]))" \ + "$repr_pattern" "Check obj exists @main 2" gdb_test "python print (blist\[0\].location)" \ "main" "Check breakpoint location @main 2" - gdb_test "python print (blist\[1\])" \ - "" "Check obj exists @mult_line" + gdb_test "python print (repr (blist\[1\]))" \ + "$repr_pattern" "Check obj exists @mult_line" gdb_test "python print (blist\[1\].location)" \ "py-breakpoint\.c:${mult_line}*" \ @@ -225,14 +227,16 @@ proc_with_prefix test_bkpt_invisible { } { return 0 } + set repr_pattern "" + delete_breakpoints set ibp_location [gdb_get_line_number "Break at multiply."] gdb_py_test_silent_cmd "python ibp = gdb.Breakpoint(\"$ibp_location\", internal=False)" \ "Set invisible breakpoint" 0 gdb_py_test_silent_cmd "python ilist = gdb.breakpoints()" \ "Get Breakpoint List" 0 - gdb_test "python print (ilist\[0\])" \ - "" "Check invisible bp obj exists 1" + gdb_test "python print (repr (ilist\[0\]))" \ + "$repr_pattern" "Check invisible bp obj exists 1" gdb_test "python print (ilist\[0\].location)" \ "py-breakpoint\.c:$ibp_location*" "Check breakpoint location 1" gdb_test "python print (ilist\[0\].visible)" \ @@ -244,8 +248,8 @@ proc_with_prefix test_bkpt_invisible { } { "Set invisible breakpoint" 0 gdb_py_test_silent_cmd "python ilist = gdb.breakpoints()" \ "Get Breakpoint List" 0 - gdb_test "python print (ilist\[0\])" \ - "" "Check invisible bp obj exists 2" + gdb_test "python print (repr (ilist\[0\]))" \ + "$repr_pattern" "Check invisible bp obj exists 2" gdb_test "python print (ilist\[0\].location)" \ "py-breakpoint\.c:$ibp_location*" "Check breakpoint location 2" gdb_test "python print (ilist\[0\].visible)" \ diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp index 9ec2f44e9c..9bd5a35ed1 100644 --- a/gdb/testsuite/gdb.python/py-symbol.exp +++ b/gdb/testsuite/gdb.python/py-symbol.exp @@ -43,6 +43,8 @@ clean_restart ${binfile} # point where we don't have a current frame, and we don't want to # require one. gdb_py_test_silent_cmd "python main_func = gdb.lookup_global_symbol(\"main\")" "Lookup main" 1 +gdb_test "python print (repr (main_func))" "" \ + "test main_func.__repr__" gdb_test "python print (main_func.is_function)" "True" "test main_func.is_function" gdb_test "python print (gdb.lookup_global_symbol(\"junk\"))" "None" "test lookup_global_symbol(\"junk\")" diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp index c245d41a1a..918216ddd6 100644 --- a/gdb/testsuite/gdb.python/py-type.exp +++ b/gdb/testsuite/gdb.python/py-type.exp @@ -388,3 +388,7 @@ if { [build_inferior "${binfile}-cxx" "c++"] == 0 } { test_type_equality } } + +# Test __repr__(). +gdb_test "python print (repr (gdb.lookup_type ('char')))" \ + "" "test __repr__()" -- 2.40.1