From: Jan Vrany <jan.vrany@labware.com>
To: gdb-patches@sourceware.org
Cc: Jan Vrany <jan.vrany@labware.com>, Eli Zaretskii <eliz@gnu.org>
Subject: [RFC v5 15/18] gdb/python: add more attributes to gdb.LinetableEntry objects
Date: Mon, 23 Jun 2025 17:10:10 +0100 [thread overview]
Message-ID: <20250623161013.650814-16-jan.vrany@labware.com> (raw)
In-Reply-To: <20250623161013.650814-1-jan.vrany@labware.com>
This commit adds is_stmt, prologue_end and epilogue_begin attributes
to linetable entry objects.
This prompted change in gdb.Linetable.line() (ltpy_get_pcs_for_line).
In order to fill initialize new attributes we need complete entries
matching the line, not only PCs.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
---
gdb/doc/python.texi | 17 ++++
gdb/python/py-linetable.c | 101 +++++++++++++++++++---
gdb/testsuite/gdb.python/py-linetable.exp | 10 +++
3 files changed, 116 insertions(+), 12 deletions(-)
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 15f851e5fd0..7c3a87cdaad 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -6822,6 +6822,23 @@ executable code for that source line resides in memory. This
attribute is not writable.
@end defvar
+@defvar LineTableEntry.is_stmt
+True if pc (associated with this entry) is a good location to place
+a breakpoint for line (associated with this entry). This attribute is not
+writable.
+@end defvar
+
+@defvar LineTableEntry.prologue_end
+True if pc (associated with this entry) is a good location to place
+a breakpoint after a function prologue. This attribute is not
+writable.
+@end defvar
+
+@defvar LineTableEntry.epilogue_begin
+True if pc (associated with this entry) marks the start of the epilogue.
+This attribute is not writable.
+@end defvar
+
As there can be multiple addresses for a single source line, you may
receive multiple @code{LineTableEntry} objects with matching
@code{line} attributes, but with different @code{pc} attributes. The
diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c
index 90cba09c88e..5eb40bf3c5b 100644
--- a/gdb/python/py-linetable.c
+++ b/gdb/python/py-linetable.c
@@ -25,6 +25,12 @@ struct linetable_entry_object {
int line;
/* The pc associated with the source line. */
CORE_ADDR pc;
+ /* See is_stmt in stuct linetable_entry. */
+ bool is_stmt : 1;
+ /* See prologue_end in stuct linetable_entry. */
+ bool prologue_end : 1;
+ /* See epilogue_begin in struct linetable_entry. */
+ bool epilogue_begin : 1;
};
extern PyTypeObject linetable_entry_object_type
@@ -98,7 +104,8 @@ symtab_to_linetable_object (PyObject *symtab)
and an address. */
static PyObject *
-build_linetable_entry (int line, CORE_ADDR address)
+build_linetable_entry (int line, CORE_ADDR address, bool is_stmt,
+ bool prologue_end, bool epilogue_begin)
{
linetable_entry_object *obj;
@@ -108,6 +115,9 @@ build_linetable_entry (int line, CORE_ADDR address)
{
obj->line = line;
obj->pc = address;
+ obj->is_stmt = is_stmt;
+ obj->prologue_end = prologue_end;
+ obj->epilogue_begin = epilogue_begin;
}
return (PyObject *) obj;
@@ -120,22 +130,26 @@ 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_entries (
+ const struct objfile *objfile,
+ const std::vector<const linetable_entry *> &entries)
{
int i;
- if (pcs.size () < 1)
+ if (entries.size () < 1)
Py_RETURN_NONE;
- gdbpy_ref<> tuple (PyTuple_New (pcs.size ()));
+ gdbpy_ref<> tuple (PyTuple_New (entries.size ()));
if (tuple == NULL)
return NULL;
- for (i = 0; i < pcs.size (); ++i)
+ for (i = 0; i < entries.size (); ++i)
{
- CORE_ADDR pc = pcs[i];
- gdbpy_ref<> obj (build_linetable_entry (line, pc));
+ auto entry = entries[i];
+ gdbpy_ref<> obj (build_linetable_entry (
+ entry->line, entry->pc (objfile), entry->is_stmt,
+ entry->prologue_end, entry->epilogue_begin));
if (obj == NULL)
return NULL;
@@ -155,24 +169,35 @@ ltpy_get_pcs_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;
+ std::vector<const linetable_entry*> entries;
LTPY_REQUIRE_VALID (self, symtab);
if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
return NULL;
+ if (! symtab->linetable ())
+ Py_RETURN_NONE;
+
try
{
- pcs = find_pcs_for_symtab_line (symtab, py_line, &best_entry);
+ const linetable_entry *entry;
+ int i;
+ for (entry = symtab->linetable ()->item, i = 0;
+ i < symtab->linetable ()->nitems;
+ entry++, i++)
+ {
+ if (entry->line == py_line)
+ entries.push_back (entry);
+ }
}
catch (const gdb_exception &except)
{
return gdbpy_handle_gdb_exception (nullptr, except);
}
- return build_line_table_tuple_from_pcs (py_line, pcs);
+ struct objfile *objfile = symtab->compunit ()->objfile ();
+ return build_line_table_tuple_from_entries (objfile, entries);
}
/* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
@@ -321,6 +346,50 @@ ltpy_entry_get_pc (PyObject *self, void *closure)
return gdb_py_object_from_ulongest (obj->pc).release ();
}
+/* Implementation of gdb.LineTableEntry.is_stmt (self) -> bool. Returns
+ True if associated PC is a good location to place a breakpoint for
+ associatated LINE. */
+
+static PyObject *
+ltpy_entry_get_is_stmt (PyObject *self, void *closure)
+{
+ linetable_entry_object *obj = (linetable_entry_object *) self;
+
+ if (obj->is_stmt != 0)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
+/* Implementation of gdb.LineTableEntry.prologue_end (self) -> bool. Returns
+ True if associated PC is a good location to place a breakpoint after a
+ function prologue. */
+
+static PyObject *
+ltpy_entry_get_prologue_end (PyObject *self, void *closure)
+{
+ linetable_entry_object *obj = (linetable_entry_object *) self;
+
+ if (obj->prologue_end)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
+/* Implementation of gdb.LineTableEntry.prologue_end (self) -> bool. Returns
+ True if this location marks the start of the epilogue. */
+
+static PyObject *
+ltpy_entry_get_epilogue_begin (PyObject *self, void *closure)
+{
+ linetable_entry_object *obj = (linetable_entry_object *) self;
+
+ if (obj->epilogue_begin)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
/* LineTable iterator functions. */
/* Return a new line table iterator. */
@@ -406,7 +475,8 @@ 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->pc (objfile), item->is_stmt,
+ item->prologue_end, item->epilogue_begin );
iter_obj->current_index++;
return obj;
@@ -534,9 +604,16 @@ static gdb_PyGetSetDef linetable_entry_object_getset[] = {
"The line number in the source file.", NULL },
{ "pc", ltpy_entry_get_pc, NULL,
"The memory address for this line number.", NULL },
+ { "is_stmt", ltpy_entry_get_is_stmt, NULL,
+ "Whether this is a good location to place a breakpoint for associated LINE.", NULL },
+ { "prologue_end", ltpy_entry_get_prologue_end, NULL,
+ "Whether this is a good location to place a breakpoint after method prologue.", NULL },
+ { "epilogue_begin", ltpy_entry_get_epilogue_begin, NULL,
+ "True if this location marks the start of the epilogue.", NULL },
{ NULL } /* Sentinel */
};
+
PyTypeObject linetable_entry_object_type = {
PyVarObject_HEAD_INIT (NULL, 0)
"gdb.LineTableEntry", /*tp_name*/
diff --git a/gdb/testsuite/gdb.python/py-linetable.exp b/gdb/testsuite/gdb.python/py-linetable.exp
index d27d16edc5d..40afd8c400e 100644
--- a/gdb/testsuite/gdb.python/py-linetable.exp
+++ b/gdb/testsuite/gdb.python/py-linetable.exp
@@ -53,6 +53,16 @@ gdb_test "python print(len(lt.line(20)))" "1" \
"Test length of a single pc line"
gdb_test "python print(lt.line(1))" "None" \
"Test None returned for line with no pc"
+gdb_test "python print(next(iter(lt)).is_stmt)" \
+ "(True|False)" \
+ "Test is_stmt"
+gdb_test "python print(next(iter(lt)).prologue_end)" \
+ "(True|False)" \
+ "Test prologue_end"
+gdb_test "python print(next(iter(lt)).epilogue_begin)" \
+ "(True|False)" \
+ "Test epilogue_begin"
+
# Test gdb.Linetable.sourcelines ()
gdb_py_test_silent_cmd "python fset = lt.source_lines()" \
--
2.47.2
next prev parent reply other threads:[~2025-06-23 16:15 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-23 16:09 [RFC v5 00/19] Add Python "JIT" API Jan Vrany
2025-06-23 16:09 ` [RFC v5 01/18] gdb: introduce expand_symtabs_maybe_overlapping Jan Vrany
2025-06-24 15:22 ` Tom Tromey
2025-06-26 15:05 ` Jan Vraný
2025-06-23 16:09 ` [RFC v5 02/18] gdb: introduce compunit_symtab::maybe_contains Jan Vrany
2025-06-23 16:09 ` [RFC v5 03/18] gdb: update is_addr_in_objfile to support "dynamic" objfiles Jan Vrany
2025-06-23 16:09 ` [RFC v5 04/18] gdb: introduce new function create_function_type Jan Vrany
2025-06-24 15:29 ` Tom Tromey
2025-06-26 11:12 ` Jan Vraný
2025-06-27 14:21 ` Tom Tromey
2025-06-27 14:30 ` Jan Vraný
2025-06-23 16:10 ` [RFC v5 05/18] gdb/python: add function () method to gdb.Type object Jan Vrany
2025-06-24 16:11 ` Tom Tromey
2025-06-26 11:13 ` Jan Vraný
2025-06-23 16:10 ` [RFC v5 06/18] gdb: use std::vector<> to hold on blocks in struct blockvector Jan Vrany
2025-06-23 16:10 ` [RFC v5 07/18] gdb/python: add gdb.Compunit Jan Vrany
2025-06-23 16:10 ` [RFC v5 08/18] gdb/python: allow instantiation of gdb.Objfile from Python Jan Vrany
2025-06-23 16:10 ` [RFC v5 09/18] gdb/python: add unlink () method to gdb.Objfile object Jan Vrany
2025-06-23 16:10 ` [RFC v5 10/18] gdb/python: allow instantiation of gdb.Compunit from Python Jan Vrany
2025-06-23 16:10 ` [RFC v5 11/18] gdb/python: allow instantiation of gdb.Symtab " Jan Vrany
2025-06-23 16:10 ` [RFC v5 12/18] gdb/python: allow instantiation of gdb.Block " Jan Vrany
2025-06-23 16:10 ` [RFC v5 13/18] gdb/python: allow instantiation of gdb.Symbol " Jan Vrany
2025-06-23 16:10 ` [RFC v5 14/18] gdb/python: add add_symbol () method to gdb.Block Jan Vrany
2025-08-29 14:10 ` Andrew Burgess
2025-08-29 14:14 ` Andrew Burgess
2025-06-23 16:10 ` Jan Vrany [this message]
2025-08-29 14:00 ` [RFC v5 15/18] gdb/python: add more attributes to gdb.LinetableEntry objects Andrew Burgess
2025-09-02 11:03 ` Jan Vraný
2025-06-23 16:10 ` [RFC v5 16/18] gdb/python: allow instantiation of gdb.LineTableEntry objects Jan Vrany
2025-06-23 16:10 ` [RFC v5 17/18] gdb/python: allow instantiation of gdb.LineTable objects Jan Vrany
2025-06-23 16:10 ` [RFC v5 18/18] gdb/python: add section in documentation on implementing JIT interface Jan Vrany
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=20250623161013.650814-16-jan.vrany@labware.com \
--to=jan.vrany@labware.com \
--cc=eliz@gnu.org \
--cc=gdb-patches@sourceware.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