summaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2017-09-05 12:07:00 -0600
committerTom Tromey <tom@tromey.com>2017-09-11 14:15:20 -0600
commit7c96f8c1dae023c7d0b1cabc5e50c4d18fd06960 (patch)
treed842c8f82408e17bde8e8e27a298d7c24a65f91c /gdb/python
parent4ec521f238627f7682306d699c8826390a2cc9e7 (diff)
Add new_inferior, inferior_deleted, and new_thread events
This adds a few new events to gdb's Python layer: new_inferior, inferior_deleted, and new_thread. I wanted to be able to add a combined inferior/thread display window to my GUI, and I needed a few events to make this work. This is PR python/15622. ChangeLog 2017-09-11 Tom Tromey <tom@tromey.com> PR python/15622: * NEWS: Add entry. * python/python.c (do_start_initialization): Initialize new event types. * python/python-internal.h (gdbpy_initialize_new_inferior_event) (gdbpy_initialize_inferior_deleted_event) (gdbpy_initialize_new_thread_event): Declare. * python/py-threadevent.c (create_thread_event_object): Add option "thread" parameter. * python/py-inferior.c (new_thread_event_object_type) (new_inferior_event_object_type) (inferior_deleted_event_object_type): Declare. (python_new_inferior, python_inferior_deleted): New functions. (add_thread_object): Emit new_thread event. (gdbpy_initialize_inferior): Attach new functions to corresponding observers. (new_thread, new_inferior, inferior_deleted): Define new event types. * python/py-evts.c (gdbpy_initialize_py_events): Add new registries. * python/py-events.h (events_object) <new_inferior, inferior_deleted, new_thread>: New fields. * python/py-event.h (create_thread_event_breakpoint): Add optional "thread" parameter. doc/ChangeLog 2017-09-11 Tom Tromey <tom@tromey.com> * python.texi (Events In Python): Document new events. testsuite/ChangeLog 2017-09-11 Tom Tromey <tom@tromey.com> * gdb.python/py-infthread.exp: Add tests for new_thread event. * gdb.python/py-inferior.exp: Add tests for new inferior events.
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-event.h3
-rw-r--r--gdb/python/py-events.h3
-rw-r--r--gdb/python/py-evts.c9
-rw-r--r--gdb/python/py-inferior.c88
-rw-r--r--gdb/python/py-threadevent.c13
-rw-r--r--gdb/python/python-internal.h6
-rw-r--r--gdb/python/python.c3
7 files changed, 118 insertions, 7 deletions
diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h
index ccb851339c..2f02c5f861 100644
--- a/gdb/python/py-event.h
+++ b/gdb/python/py-event.h
@@ -125,7 +125,8 @@ extern int evpy_emit_event (PyObject *event,
eventregistry_object *registry);
extern PyObject *create_event_object (PyTypeObject *py_type);
-extern PyObject *create_thread_event_object (PyTypeObject *py_type);
+extern PyObject *create_thread_event_object (PyTypeObject *py_type,
+ PyObject *thread = nullptr);
extern int emit_new_objfile_event (struct objfile *objfile);
extern int emit_clear_objfiles_event (void);
diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h
index 348dabc922..2275d896e6 100644
--- a/gdb/python/py-events.h
+++ b/gdb/python/py-events.h
@@ -47,6 +47,9 @@ typedef struct
eventregistry_object *exited;
eventregistry_object *new_objfile;
eventregistry_object *clear_objfiles;
+ eventregistry_object *new_inferior;
+ eventregistry_object *inferior_deleted;
+ eventregistry_object *new_thread;
eventregistry_object *inferior_call;
eventregistry_object *memory_changed;
eventregistry_object *register_changed;
diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c
index 126d18cead..ad9924190c 100644
--- a/gdb/python/py-evts.c
+++ b/gdb/python/py-evts.c
@@ -89,6 +89,15 @@ gdbpy_initialize_py_events (void)
if (add_new_registry (&gdb_py_events.clear_objfiles, "clear_objfiles") < 0)
return -1;
+ if (add_new_registry (&gdb_py_events.new_inferior, "new_inferior") < 0)
+ return -1;
+
+ if (add_new_registry (&gdb_py_events.inferior_deleted, "inferior_deleted") < 0)
+ return -1;
+
+ if (add_new_registry (&gdb_py_events.new_thread, "new_thread") < 0)
+ return -1;
+
if (add_new_registry (&gdb_py_events.breakpoint_created,
"breakpoint_created") < 0)
return -1;
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index f6a24a090f..d7c6810884 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -30,6 +30,13 @@
#include "py-event.h"
#include "py-stopevent.h"
+extern PyTypeObject new_thread_event_object_type
+ CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
+extern PyTypeObject new_inferior_event_object_type
+ CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
+extern PyTypeObject inferior_deleted_event_object_type
+ CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
+
struct threadlist_entry {
thread_object *thread_obj;
struct threadlist_entry *next;
@@ -235,6 +242,60 @@ inferior_to_inferior_object (struct inferior *inferior)
return (PyObject *) inf_obj;
}
+/* Called when a new inferior is created. Notifies any Python event
+ listeners. */
+static void
+python_new_inferior (struct inferior *inf)
+{
+ if (!gdb_python_initialized)
+ return;
+
+ gdbpy_enter enter_py (python_gdbarch, python_language);
+
+ if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
+ return;
+
+ gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf));
+ if (inf_obj == NULL)
+ {
+ gdbpy_print_stack ();
+ return;
+ }
+
+ gdbpy_ref<> event (create_event_object (&new_inferior_event_object_type));
+ if (event == NULL
+ || evpy_add_attribute (event.get (), "inferior", inf_obj.get ()) < 0
+ || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
+ gdbpy_print_stack ();
+}
+
+/* Called when an inferior is removed. Notifies any Python event
+ listeners. */
+static void
+python_inferior_deleted (struct inferior *inf)
+{
+ if (!gdb_python_initialized)
+ return;
+
+ gdbpy_enter enter_py (python_gdbarch, python_language);
+
+ if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
+ return;
+
+ gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf));
+ if (inf_obj == NULL)
+ {
+ gdbpy_print_stack ();
+ return;
+ }
+
+ gdbpy_ref<> event (create_event_object (&inferior_deleted_event_object_type));
+ if (event == NULL
+ || evpy_add_attribute (event.get (), "inferior", inf_obj.get ()) < 0
+ || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
+ gdbpy_print_stack ();
+}
+
/* Finds the Python Inferior object for the given PID. Returns a
reference, or NULL if PID does not match any inferior object. */
@@ -298,6 +359,15 @@ add_thread_object (struct thread_info *tp)
inf_obj->threads = entry;
inf_obj->nthreads++;
+
+ if (evregpy_no_listeners_p (gdb_py_events.new_thread))
+ return;
+
+ gdbpy_ref<> event (create_thread_event_object (&new_thread_event_object_type,
+ (PyObject *) thread_obj));
+ if (event == NULL
+ || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
+ gdbpy_print_stack ();
}
static void
@@ -823,6 +893,8 @@ gdbpy_initialize_inferior (void)
observer_attach_register_changed (python_on_register_change);
observer_attach_inferior_exit (python_inferior_exit);
observer_attach_new_objfile (python_new_objfile);
+ observer_attach_inferior_added (python_new_inferior);
+ observer_attach_inferior_removed (python_inferior_deleted);
membuf_object_type.tp_new = PyType_GenericNew;
if (PyType_Ready (&membuf_object_type) < 0)
@@ -970,3 +1042,19 @@ PyTypeObject membuf_object_type = {
0, /* tp_init */
0, /* tp_alloc */
};
+
+GDBPY_NEW_EVENT_TYPE (new_thread,
+ "gdb.NewThreadEvent",
+ "NewThreadEvent",
+ "GDB new thread event object",
+ thread_event_object_type);
+GDBPY_NEW_EVENT_TYPE (new_inferior,
+ "gdb.NewInferiorEvent",
+ "NewInferiorEvent",
+ "GDB new inferior event object",
+ event_object_type);
+GDBPY_NEW_EVENT_TYPE (inferior_deleted,
+ "gdb.InferiorDeletedEvent",
+ "InferiorDeletedEvent",
+ "GDB inferior deleted event object",
+ event_object_type);
diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c
index 921744442f..7211fa26da 100644
--- a/gdb/python/py-threadevent.c
+++ b/gdb/python/py-threadevent.c
@@ -48,17 +48,18 @@ get_event_thread (void)
}
PyObject *
-create_thread_event_object (PyTypeObject *py_type)
+create_thread_event_object (PyTypeObject *py_type, PyObject *thread)
{
- PyObject *thread = NULL;
-
gdbpy_ref<> thread_event_obj (create_event_object (py_type));
if (thread_event_obj == NULL)
return NULL;
- thread = get_event_thread ();
- if (!thread)
- return NULL;
+ if (thread == NULL)
+ {
+ thread = get_event_thread ();
+ if (!thread)
+ return NULL;
+ }
if (evpy_add_attribute (thread_event_obj.get (),
"inferior_thread",
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index ebb83f0cba..0c3582f180 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -630,6 +630,12 @@ int gdbpy_initialize_new_objfile_event (void)
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
int gdbpy_initialize_clear_objfiles_event (void)
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
+int gdbpy_initialize_new_inferior_event (void)
+ CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
+int gdbpy_initialize_inferior_deleted_event (void)
+ CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
+int gdbpy_initialize_new_thread_event (void)
+ CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
int gdbpy_initialize_arch (void)
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
int gdbpy_initialize_xmethods (void)
diff --git a/gdb/python/python.c b/gdb/python/python.c
index b086cef251..fbb4747c5f 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1603,6 +1603,9 @@ do_start_initialization ()
|| gdbpy_initialize_thread_event () < 0
|| gdbpy_initialize_new_objfile_event () < 0
|| gdbpy_initialize_clear_objfiles_event () < 0
+ || gdbpy_initialize_new_inferior_event () < 0
+ || gdbpy_initialize_inferior_deleted_event () < 0
+ || gdbpy_initialize_new_thread_event () < 0
|| gdbpy_initialize_arch () < 0
|| gdbpy_initialize_xmethods () < 0
|| gdbpy_initialize_unwind () < 0)