aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorMatheus Branco Borella <dark.ryu.550@gmail.com>2023-05-18 00:33:57 -0300
committerAndrew Burgess <aburgess@redhat.com>2023-07-04 12:07:16 +0100
commitbb2bd584f31a25ba1cfe5bdac4d07d8cffe87c3d (patch)
tree8dac0966bc63e625f87af8e1a6a2243e15df3803 /gdb/python
parentb8c2de06bcbc13a1a6b93163cf675272d7eada9f (diff)
downloadgdb-bb2bd584f31a25ba1cfe5bdac4d07d8cffe87c3d.zip
gdb-bb2bd584f31a25ba1cfe5bdac4d07d8cffe87c3d.tar.gz
gdb-bb2bd584f31a25ba1cfe5bdac4d07d8cffe87c3d.tar.bz2
gdb: add __repr__() implementation to a few Python types
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, gdb.BreakpointLocation, 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.Type code=TYPE_CODE_INT name=char> >> gdb.lookup_global_symbol("main") <gdb.Symbol print_name=main> The gdb.Block.__repr__() method shows the first 5 symbols from the block, and then a message to show how many more were elided (if any).
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-arch.c17
-rw-r--r--gdb/python/py-block.c37
-rw-r--r--gdb/python/py-breakpoint.c67
-rw-r--r--gdb/python/py-symbol.c15
-rw-r--r--gdb/python/py-type.c30
5 files changed, 160 insertions, 6 deletions
diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c
index 4d133d1..ac51933 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 09fa74d..dd6d6d2 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 () : "<anonymous>";
+
+ 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 d11fc64..fa1570e 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 ff3d185..ee863aa 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 b9fa741..b4d1e23 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*/