diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c index 4d133d1fe14..ac519331f18 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); + + auto arch_info = gdbarch_bfd_arch_info (gdbarch); + return PyUnicode_FromFormat ("<%s arch_name=%s printable_name=%s>", + Py_TYPE (self)->tp_name, arch_info->arch_name, + arch_info->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 09fa74d862c..dd6d6d278a0 100644 --- a/gdb/python/py-block.c +++ b/gdb/python/py-block.c @@ -418,6 +418,41 @@ 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 ()); + static constexpr int SYMBOLS_TO_SHOW = 5; + for (struct symbol *symbol : block_iterator_range (block)) + { + if (written_symbols == SYMBOLS_TO_SHOW) + { + const int remaining = len - SYMBOLS_TO_SHOW; + if (remaining == 1) + str += string_printf ("... (%d more symbol)", remaining); + else + str += string_printf ("... (%d more symbols)", remaining); + break; + } + str += symbol->print_name (); + if (++written_symbols < len) + str += ", "; + } + 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 +517,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 d11fc64df20..fa1570e1a04 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,31 @@ 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%s number=%d hits=%d%s>", + Py_TYPE (self)->tp_name, + (bp->bp->enable_state == bp_enabled + ? "" : " disabled"), 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 +1432,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 +1650,43 @@ 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 += string_printf (" address=%s", + paddress (self->bp_loc->owner->gdbarch, + self->bp_loc->address)); + + if (self->bp_loc->requested_address != self->bp_loc->address) + str += string_printf (" requested_address=%s", + paddress (self->bp_loc->owner->gdbarch, + self->bp_loc->requested_address)); + if (self->bp_loc->symtab != nullptr) + str += string_printf (" source=%s:%d", self->bp_loc->symtab->filename, + 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 +1718,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 ff3d18504e7..ee863aa4df4 100644 --- a/gdb/python/py-symbol.c +++ b/gdb/python/py-symbol.c @@ -378,6 +378,19 @@ 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 +754,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 b9fa741177f..b4d1e230b3b 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -1028,6 +1028,34 @@ 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 +1645,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 4f4b4aa766f..597943ff682 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 a0c6e165605..dd2e195af4a 100644 --- a/gdb/testsuite/gdb.python/py-block.c +++ b/gdb/testsuite/gdb.python/py-block.c @@ -30,9 +30,40 @@ int block_func (void) } } +/* A function with no locals. Used for testing gdb.Block.__repr__(). */ +int no_locals_func (void) +{ + return block_func (); +} + +/* A function with 5 locals. Used for testing gdb.Block.__repr__(). */ +int few_locals_func (void) +{ + int i = 0; + int j = 0; + int k = 0; + int x = 0; + int y = 0; + return block_func (); +} + +/* A function with 6 locals. Used for testing gdb.Block.__repr__(). */ +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 3bdf97294ae..37e3105b4e3 100644 --- a/gdb/testsuite/gdb.python/py-block.exp +++ b/gdb/testsuite/gdb.python/py-block.exp @@ -38,7 +38,8 @@ 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)" " \{i, f, b\}>" \ + "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 +69,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-bp-locations.exp b/gdb/testsuite/gdb.python/py-bp-locations.exp index f8649f6c105..b3a8c83bc0a 100644 --- a/gdb/testsuite/gdb.python/py-bp-locations.exp +++ b/gdb/testsuite/gdb.python/py-bp-locations.exp @@ -31,6 +31,30 @@ if ![runto_main] { return -1 } +# Build a regexp string that represents the __repr__ of a +# gdb.BreakpointLocation object. Accepts arguments -enabled, -address, +# -source, -line, and -func. +proc build_bpl_regexp { args } { + parse_args [list {enabled True} [list address "$::hex"] {source ".*"} \ + [list line "$::decimal"] {func ""}] + + set pattern "" + return $pattern +} + # Set breakpoint with 2 locations. gdb_breakpoint "add" @@ -42,9 +66,17 @@ gdb_test "python print(gdb.breakpoints()\[1\].locations\[0\].source)" \ ".*('.*py-bp-locations.c', $expected_line_a).*" gdb_test "python print(gdb.breakpoints()\[1\].locations\[1\].source)" \ ".*('.*py-bp-locations.c', $expected_line_b).*" +gdb_test "python print(gdb.breakpoints()\[1\].locations\[1\])" \ + [build_bpl_regexp -enabled True -source ".*py-bp-locations.c" \ + -line "$expected_line_b" -func ".*"] \ + "check repr of enabled breakpoint location" # Disable first location and make sure we don't hit it. gdb_test "python gdb.breakpoints()\[1\].locations\[0\].enabled = False" "" +gdb_test "python print(gdb.breakpoints()\[1\].locations\[0\])" \ + [build_bpl_regexp -enabled False -source ".*py-bp-locations.c" \ + -line "$expected_line_a" -func ".*"] \ + "check repr of disabled breakpoint location" gdb_continue_to_breakpoint "" ".*25.*" if ![runto_main] { diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 76094c95d10..df17d646b28 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -38,6 +38,36 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} ${options}] set past_throw_catch_line [gdb_get_line_number "Past throw-catch."] +# Build a regexp string that can match against the repr of a gdb.Breakpoint +# object. Accepts arguments -enabled, -number, -hits, -thread, -task, and +# -enable_count. The -enabled argument is a boolean, while all of the others +# take a regexp string. +proc build_bp_repr { args } { + parse_args [list {enabled True} [list number "-?$::decimal"] \ + [list hits $::decimal] {thread ""} {task ""} \ + {enable_count ""}] + + set pattern "" + return $pattern +} + proc_with_prefix test_bkpt_basic { } { global srcfile testfile hex decimal @@ -54,8 +84,8 @@ proc_with_prefix test_bkpt_basic { } { # 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\]))" \ + [build_bp_repr -number 1 -hits 1] "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 +102,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\]))" \ + [build_bp_repr -number 1 -hits 1] "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\]))" \ + [build_bp_repr -number 2 -hits 1] "Check obj exists @mult_line" gdb_test "python print (blist\[1\].location)" \ "py-breakpoint\.c:${mult_line}*" \ @@ -102,6 +132,9 @@ proc_with_prefix test_bkpt_basic { } { "True" "Check breakpoint enabled." gdb_py_test_silent_cmd "python blist\[1\].enabled = False" \ "Set breakpoint disabled." 0 + gdb_test "python print (repr (blist\[1\]))" \ + [build_bp_repr -enabled False -number 2 -hits 6] \ + "Check repr for a disabled breakpoint" gdb_continue_to_breakpoint "Break at add 2" ".*Break at add.*" gdb_py_test_silent_cmd "python blist\[1\].enabled = True" \ "Set breakpoint enabled." 0 @@ -113,6 +146,13 @@ proc_with_prefix test_bkpt_basic { } { "Get Breakpoint List" 0 gdb_test "python print (blist\[1\].thread)" \ "None" "Check breakpoint thread" + gdb_py_test_silent_cmd "python blist\[1\].thread = 1" \ + "set breakpoint thread" 0 + gdb_test "python print (repr (blist\[1\]))" \ + [build_bp_repr -number 2 -hits 7 -thread 1] \ + "Check repr for a thread breakpoint" + gdb_py_test_silent_cmd "python blist\[1\].thread = None" \ + "clear breakpoint thread" 0 gdb_test "python print (blist\[1\].type == gdb.BP_BREAKPOINT)" \ "True" "Check breakpoint type" gdb_test "python print (blist\[0\].number)" \ @@ -231,8 +271,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 1" + gdb_test "python print (repr (ilist\[0\]))" \ + [build_bp_repr -number 2 -hits 0] "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 +284,9 @@ 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\]))" \ + [build_bp_repr -number "-$decimal" -hits 0] \ + "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)" \ @@ -835,6 +876,14 @@ proc_with_prefix test_bkpt_auto_disable { } { set mult_line [gdb_get_line_number "Break at multiply."] gdb_breakpoint ${mult_line} gdb_test_no_output "enable count 1 2" "one shot enable" + + # Find the Python gdb.Breakpoint object for breakpoint #2. + gdb_py_test_silent_cmd \ + "python bp = \[b for b in gdb.breakpoints() if b.number == 2\]\[0\]" \ + "Get breakpoint number 2" 0 + gdb_test "python print (repr (bp))" \ + [build_bp_repr -number 2 -hits 0 -enable_count 1] + # Python 2 doesn't support print in lambda function, so use a named # function instead. gdb_test_multiline "Define print_bp_enabled" \ diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp index 9ec2f44e9c0..9bd5a35ed1c 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 c245d41a1ac..918216ddd69 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__()"