From: Simon Farre <simon.farre.cx@gmail.com>
To: gdb-patches@sourceware.org
Cc: tom@tromey.org, Simon Farre <simon.farre.cx@gmail.com>
Subject: [PATCH v3 3/5] [dap & linetable]: Change gdb.LineTableEntry & Add gdb.lookup_linetable
Date: Mon, 22 Jan 2024 14:31:13 +0100 [thread overview]
Message-ID: <20240122133115.201205-3-simon.farre.cx@gmail.com> (raw)
In-Reply-To: <20240122133115.201205-1-simon.farre.cx@gmail.com>
This patch changes the Python type `LineTableEntry` by adding the
`column` accessor which returns the newly added `column` value from the
internal linetable_entry.
It also exposes a new "module function": gdb.lookup_linetable which
searches all symbtabs using a string; comparing it with the symtabs
'fullname' and returning the linetable of the (first) symtab that
matches.
To search for a linetable from python:
lt = gdb.lookup_linetable("main.cpp")
And like before (as per current documentation), one can use that like so:
for lte in lt:
print(f"line:col={lte.line}:{lte.column}; pc = {hex(lte.pc)}")
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31271
---
gdb/python/py-linetable.c | 35 ++++++++++++++++++++++++-----------
gdb/python/py-symtab.c | 33 +++++++++++++++++++++++++++++++++
gdb/python/python-internal.h | 2 ++
gdb/python/python.c | 2 ++
gdb/symtab.c | 19 ++++++++++++++++++-
gdb/symtab.h | 3 +++
6 files changed, 82 insertions(+), 12 deletions(-)
diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c
index 788a6e1e24b..ba96c663027 100644
--- a/gdb/python/py-linetable.c
+++ b/gdb/python/py-linetable.c
@@ -24,6 +24,8 @@ struct linetable_entry_object {
PyObject_HEAD
/* The line table source line. */
int line;
+ /* The line table source column. */
+ int col;
/* The pc associated with the source line. */
CORE_ADDR pc;
};
@@ -99,7 +101,7 @@ symtab_to_linetable_object (PyObject *symtab)
and an address. */
static PyObject *
-build_linetable_entry (int line, CORE_ADDR address)
+build_linetable_entry (int line, int col, CORE_ADDR address)
{
linetable_entry_object *obj;
@@ -109,6 +111,7 @@ build_linetable_entry (int line, CORE_ADDR address)
{
obj->line = line;
obj->pc = address;
+ obj->col = col;
}
return (PyObject *) obj;
@@ -121,7 +124,7 @@ build_linetable_entry (int line, CORE_ADDR address)
address. */
static PyObject *
-build_line_table_tuple_from_pcs (int line, const std::vector<CORE_ADDR> &pcs)
+build_line_table_tuple_from_pcs (int line, const symtab& sym, const std::vector<linetable_entry> &pcs)
{
int i;
@@ -133,10 +136,11 @@ build_line_table_tuple_from_pcs (int line, const std::vector<CORE_ADDR> &pcs)
if (tuple == NULL)
return NULL;
+ const auto of = sym.compunit ()->objfile ();
for (i = 0; i < pcs.size (); ++i)
{
- CORE_ADDR pc = pcs[i];
- gdbpy_ref<> obj (build_linetable_entry (line, pc));
+ const auto& lte = pcs[i];
+ gdbpy_ref<> obj (build_linetable_entry (line, lte.col, lte.pc (of)));
if (obj == NULL)
return NULL;
@@ -152,12 +156,10 @@ build_line_table_tuple_from_pcs (int line, const std::vector<CORE_ADDR> &pcs)
in the line table. */
static PyObject *
-ltpy_get_pcs_for_line (PyObject *self, PyObject *args)
+ltpy_get_ltes_for_line (PyObject *self, PyObject *args)
{
struct symtab *symtab;
gdb_py_longest py_line;
- const linetable_entry *best_entry = nullptr;
- std::vector<CORE_ADDR> pcs;
LTPY_REQUIRE_VALID (self, symtab);
@@ -166,14 +168,15 @@ ltpy_get_pcs_for_line (PyObject *self, PyObject *args)
try
{
- pcs = find_pcs_for_symtab_line (symtab, py_line, &best_entry);
+ const auto ltes = find_ltes_for_symtab_line (*symtab, py_line);
+ return build_line_table_tuple_from_pcs (py_line, *symtab, ltes);
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- return build_line_table_tuple_from_pcs (py_line, pcs);
+ Py_RETURN_NONE;
}
/* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
@@ -327,6 +330,14 @@ ltpy_entry_get_line (PyObject *self, void *closure)
return gdb_py_object_from_longest (obj->line).release ();
}
+static PyObject *
+ltpy_entry_get_column (PyObject *self, void *closure)
+{
+ linetable_entry_object *obj = (linetable_entry_object *) self;
+
+ return gdb_py_object_from_longest (obj->col).release ();
+}
+
/* Implementation of gdb.LineTableEntry.pc (self) -> Long. Returns a
a long integer associated with the PC of the line table entry. */
@@ -422,7 +433,7 @@ ltpy_iternext (PyObject *self)
}
struct objfile *objfile = symtab->compunit ()->objfile ();
- obj = build_linetable_entry (item->line, item->pc (objfile));
+ obj = build_linetable_entry (item->line, item->col, item->pc (objfile));
iter_obj->current_index++;
return obj;
@@ -451,7 +462,7 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_linetable);
\f
static PyMethodDef linetable_object_methods[] = {
- { "line", ltpy_get_pcs_for_line, METH_VARARGS,
+ { "line", ltpy_get_ltes_for_line, METH_VARARGS,
"line (lineno) -> Tuple\n\
Return executable locations for a given source line." },
{ "has_line", ltpy_has_line, METH_VARARGS,
@@ -548,6 +559,8 @@ PyTypeObject ltpy_iterator_object_type = {
static gdb_PyGetSetDef linetable_entry_object_getset[] = {
{ "line", ltpy_entry_get_line, NULL,
"The line number in the source file.", NULL },
+ { "column", ltpy_entry_get_column, NULL,
+ "The column number in the source file", NULL },
{ "pc", ltpy_entry_get_pc, NULL,
"The memory address for this line number.", NULL },
{ NULL } /* Sentinel */
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
index b28f6ca8b48..e23c02aa0e4 100644
--- a/gdb/python/py-symtab.c
+++ b/gdb/python/py-symtab.c
@@ -475,6 +475,39 @@ symtab_to_symtab_object (struct symtab *symtab)
return (PyObject *) symtab_obj;
}
+/* Search for a symtab whose fullname contains FILENAME and return it's
+ linetable. */
+PyObject *
+gdbpy_lookup_linetable_by_filename (PyObject *, PyObject *args, PyObject *kw)
+{
+ const char *arg = nullptr;
+ static const char *keywords[] = { "filename", nullptr };
+
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &arg))
+ {
+ return nullptr;
+ }
+
+ for (objfile *objfile : current_program_space->objfiles ())
+ for (compunit_symtab *cu : objfile->compunits ())
+ for (symtab *s : cu->filetabs ())
+ {
+ const auto name = symtab_to_fullname (s);
+
+ if (strstr (name, arg))
+ {
+ auto symtab_pyobj = symtab_to_symtab_object (s);
+ if (!symtab_pyobj)
+ Py_RETURN_NONE;
+ auto lt_obj = symtab_to_linetable_object (symtab_pyobj);
+ if (!lt_obj)
+ Py_RETURN_NONE;
+ return lt_obj;
+ }
+ }
+ Py_RETURN_NONE;
+}
+
/* Create a new symtab and line (gdb.Symtab_and_line) object
that encapsulates the symtab_and_line structure from GDB. */
PyObject *
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 7c05007cbab..dcfc03e3beb 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -408,6 +408,8 @@ PyObject *gdbpy_convenience_variable (PyObject *self, PyObject *args);
PyObject *gdbpy_set_convenience_variable (PyObject *self, PyObject *args);
PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
+PyObject *gdbpy_lookup_linetable_by_filename (PyObject *, PyObject* args,
+ PyObject *kw);
PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw);
PyObject *gdbpy_lookup_global_symbol (PyObject *self, PyObject *args,
PyObject *kw);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 1d406392bd3..3d7c70fed09 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -2573,6 +2573,8 @@ gdbpy_initialized (const struct extension_language_defn *extlang)
PyMethodDef python_GdbMethods[] =
{
+ { "lookup_linetable", (PyCFunction) gdbpy_lookup_linetable_by_filename,
+ METH_VARARGS | METH_KEYWORDS },
{ "history", gdbpy_history, METH_VARARGS,
"Get a value from history" },
{ "add_history", gdbpy_add_history, METH_VARARGS,
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 7c0a69108d4..e206ba9cada 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3519,7 +3519,24 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
return result;
}
-\f
+/** Return line table entries for SYMTAB at LINE. */
+
+std::vector<linetable_entry>
+find_ltes_for_symtab_line (const symtab &symtab, int line)
+{
+ auto lte = symtab.linetable ();
+ if (lte == nullptr)
+ return {};
+
+ std::vector<linetable_entry> result;
+ for (auto i = 0; i < lte->nitems; ++i)
+ {
+ if (lte->item[i].line == line)
+ result.push_back (lte->item[i]);
+ }
+ return result;
+}
+
/* Set the PC value for a given source file and line number and return true.
Returns false for invalid line number (and sets the PC to 0).
The source file is specified with a struct symtab. */
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 38d08fe8599..9098822c90b 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2772,6 +2772,9 @@ void iterate_over_symtabs (const char *name,
std::vector<CORE_ADDR> find_pcs_for_symtab_line
(struct symtab *symtab, int line, const linetable_entry **best_entry);
+std::vector<linetable_entry> find_ltes_for_symtab_line
+ (const symtab &symtab, int line);
+
/* Prototype for callbacks for LA_ITERATE_OVER_SYMBOLS. The callback
is called once per matching symbol SYM. The callback should return
true to indicate that LA_ITERATE_OVER_SYMBOLS should continue
--
2.43.0
next prev parent reply other threads:[~2024-01-22 13:31 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-22 13:31 [PATCH v3 1/5] [dap & linetable]: Add column to linetable entry Simon Farre
2024-01-22 13:31 ` [PATCH v3 2/5] [dap & linetable]: Add column to maint info linetable output Simon Farre
2024-02-07 19:52 ` Tom Tromey
2024-01-22 13:31 ` Simon Farre [this message]
2024-02-07 20:05 ` [PATCH v3 3/5] [dap & linetable]: Change gdb.LineTableEntry & Add gdb.lookup_linetable Tom Tromey
2024-01-22 13:31 ` [PATCH v3 4/5] [dap & linetable]: Add breakpointLocations request Simon Farre
2024-02-07 19:44 ` Tom Tromey
2024-01-22 13:31 ` [PATCH v3 5/5] [dap & linetable]: Added docs Simon Farre
2024-02-07 19:28 ` [PATCH v3 1/5] [dap & linetable]: Add column to linetable entry Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240122133115.201205-3-simon.farre.cx@gmail.com \
--to=simon.farre.cx@gmail.com \
--cc=gdb-patches@sourceware.org \
--cc=tom@tromey.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).