diff options
author | Tom Tromey <tromey@adacore.com> | 2022-06-20 11:30:04 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2022-07-18 11:25:34 -0600 |
commit | 0b4fe76f956293778f109764911a0b14dc944f5d (patch) | |
tree | a49d8074a33c86ea64a1f797ab3ecb99ad0597c4 /gdb/python | |
parent | 23948f56021f46bb2bdee7afad074aafe8329230 (diff) | |
download | gdb-0b4fe76f956293778f109764911a0b14dc944f5d.zip gdb-0b4fe76f956293778f109764911a0b14dc944f5d.tar.gz gdb-0b4fe76f956293778f109764911a0b14dc944f5d.tar.bz2 |
Add gdb.free_objfile event registry
Currently, Python code can use event registries to detect when gdb
loads a new objfile, and when gdb clears the objfile list. However,
there's no way to detect the removal of an objfile, say when the
inferior calls dlclose.
This patch adds a gdb.free_objfile event registry and arranges for an
event to be emitted in this case.
Diffstat (limited to 'gdb/python')
-rw-r--r-- | gdb/python/py-all-events.def | 1 | ||||
-rw-r--r-- | gdb/python/py-event-types.def | 5 | ||||
-rw-r--r-- | gdb/python/py-event.h | 1 | ||||
-rw-r--r-- | gdb/python/py-inferior.c | 15 | ||||
-rw-r--r-- | gdb/python/py-newobjfileevent.c | 36 |
5 files changed, 58 insertions, 0 deletions
diff --git a/gdb/python/py-all-events.def b/gdb/python/py-all-events.def index 7db8efa..e8ae906 100644 --- a/gdb/python/py-all-events.def +++ b/gdb/python/py-all-events.def @@ -27,6 +27,7 @@ GDB_PY_DEFINE_EVENT(stop) GDB_PY_DEFINE_EVENT(cont) GDB_PY_DEFINE_EVENT(exited) GDB_PY_DEFINE_EVENT(new_objfile) +GDB_PY_DEFINE_EVENT(free_objfile) GDB_PY_DEFINE_EVENT(clear_objfiles) GDB_PY_DEFINE_EVENT(new_inferior) GDB_PY_DEFINE_EVENT(inferior_deleted) diff --git a/gdb/python/py-event-types.def b/gdb/python/py-event-types.def index 596e68a..e613e69 100644 --- a/gdb/python/py-event-types.def +++ b/gdb/python/py-event-types.def @@ -86,6 +86,11 @@ GDB_PY_DEFINE_EVENT_TYPE (new_objfile, "GDB new object file event object", event_object_type); +GDB_PY_DEFINE_EVENT_TYPE (free_objfile, + "FreeObjFileEvent", + "GDB free object file event object", + event_object_type); + GDB_PY_DEFINE_EVENT_TYPE (clear_objfiles, "ClearObjFilesEvent", "GDB clear object files event object", diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h index 831dd10..220af1f 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -74,6 +74,7 @@ extern gdbpy_ref<> create_thread_event_object (PyTypeObject *py_type, PyObject *thread); extern int emit_new_objfile_event (struct objfile *objfile); +extern int emit_free_objfile_event (struct objfile *objfile); extern int emit_clear_objfiles_event (void); extern void evpy_dealloc (PyObject *self); diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index ebcd5b0..61ed342 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -197,6 +197,20 @@ python_new_objfile (struct objfile *objfile) } } +/* Emit a Python event when an objfile is about to be removed. */ + +static void +python_free_objfile (struct objfile *objfile) +{ + if (!gdb_python_initialized) + return; + + gdbpy_enter enter_py (objfile->arch ()); + + if (emit_free_objfile_event (objfile) < 0) + gdbpy_print_stack (); +} + /* Return a reference to the Python object of type Inferior representing INFERIOR. If the object has already been created, return it and increment the reference count, otherwise, create it. @@ -853,6 +867,7 @@ gdbpy_initialize_inferior (void) gdb::observers::new_objfile.attach (python_new_objfile, "py-inferior", { &auto_load_new_objfile_observer_token }); + gdb::observers::free_objfile.attach (python_free_objfile, "py-inferior"); gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior"); gdb::observers::inferior_removed.attach (python_inferior_deleted, "py-inferior"); diff --git a/gdb/python/py-newobjfileevent.c b/gdb/python/py-newobjfileevent.c index dcbd0fa..929d0ea 100644 --- a/gdb/python/py-newobjfileevent.c +++ b/gdb/python/py-newobjfileevent.c @@ -53,6 +53,42 @@ emit_new_objfile_event (struct objfile *objfile) return -1; } +/* Create an event object representing a to-be-freed objfile. Return + nullptr, with the Python exception set, on error. */ + +static gdbpy_ref<> +create_free_objfile_event_object (struct objfile *objfile) +{ + gdbpy_ref<> objfile_event + = create_event_object (&free_objfile_event_object_type); + if (objfile_event == nullptr) + return nullptr; + + gdbpy_ref<> py_objfile = objfile_to_objfile_object (objfile); + if (py_objfile == nullptr + || evpy_add_attribute (objfile_event.get (), "objfile", + py_objfile.get ()) < 0) + return nullptr; + + return objfile_event; +} + +/* Callback function which notifies observers when a free objfile + event occurs. This function will create a new Python event object. + Return -1 if emit fails. */ + +int +emit_free_objfile_event (struct objfile *objfile) +{ + if (evregpy_no_listeners_p (gdb_py_events.free_objfile)) + return 0; + + gdbpy_ref<> event = create_free_objfile_event_object (objfile); + if (event == nullptr) + return -1; + return evpy_emit_event (event.get (), gdb_py_events.free_objfile); +} + /* Subroutine of emit_clear_objfiles_event to simplify it. */ |