aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2022-06-20 11:30:04 -0600
committerTom Tromey <tromey@adacore.com>2022-07-18 11:25:34 -0600
commit0b4fe76f956293778f109764911a0b14dc944f5d (patch)
treea49d8074a33c86ea64a1f797ab3ecb99ad0597c4 /gdb/python
parent23948f56021f46bb2bdee7afad074aafe8329230 (diff)
downloadgdb-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.def1
-rw-r--r--gdb/python/py-event-types.def5
-rw-r--r--gdb/python/py-event.h1
-rw-r--r--gdb/python/py-inferior.c15
-rw-r--r--gdb/python/py-newobjfileevent.c36
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. */