public inbox for archer@sourceware.org
 help / color / mirror / Atom feed
* [RFC][1/5] Changes to the current branch
@ 2009-08-23 15:34 Oguz Kayral
  2009-09-21 21:52 ` Tom Tromey
  0 siblings, 1 reply; 2+ messages in thread
From: Oguz Kayral @ 2009-08-23 15:34 UTC (permalink / raw)
  To: archer

This patch contains the necessary changes in the current python
internals for adding event handling functionality.

--------

* Makefile.in (SUBDIR_PYTHON_OBS): Add python-{event, stopevent,
signalstopevent, breakpointstopevent, continueevent, exitedevent,
eventregistry}.o
                       (SUBDIR_PYTHON_SRCS): Add python-{event,
stopevent, signalstopevent, breakpointstopevent, continueevent,
exitedevent, eventregistry}.c
                       (python-{event, stopevent, signalstopevent,
breakpointstopevent, continueevent, exitedevent, eventregistry}.o):
New targets.
                       (PY_FILES): Add gdb/command/check_segfault.py &
gdb/command/test_events.py

* python-breakpoint.c
                        Move struct breakpoint_object from
python-breakpoint.c to python-internal.h. (for use in
python-breakpointstopevent.c)
                        (gdbpy_breakpoint_from_bpstats): New function
for getting the breakpoint object for the given bpstats.

* python-inferior.c (python_on_resume): Add new function for handling
continue events.
                                (python_on_normal_stop): Add new
function for handling stop events.
                                (python_thread_exit): Add new function
for handling exited events.
                                (infpy_threads): Attach new callbacks.

* python-infthread.c (create_thread_object): Add creation of event registries.

* python-internal.h
                         New structs for event and stop events
objects. Breakpoint object is moved from python-breakpoint.c

* python.c
                         Initialize events and event registries.

--------

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index a30cfdc..05fcd3e 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -286,7 +286,14 @@ SUBDIR_PYTHON_OBS = \
 	python-symtab.o \
 	python-type.o \
 	python-utils.o \
-	python-value.o
+	python-value.o \
+	python-event.o \
+	python-stopevent.o \
+	python-signalstopevent.o \
+	python-breakpointstopevent.o \
+	python-continueevent.o \
+	python-exitedevent.o \
+	python-eventregistry.o
 SUBDIR_PYTHON_SRCS = \
 	python/python.c \
 	python/python-block.c \
@@ -304,7 +311,14 @@ SUBDIR_PYTHON_SRCS = \
 	python/python-symtab.c \
 	python/python-type.c \
 	python/python-utils.c \
-	python/python-value.c
+	python/python-value.c \
+	python/python-event.c \
+	python/python-stopevent.c \
+	python/python-signalstopevent.c \
+	python/python-breakpointstopevent.c \
+	python/python-continueevent.c \
+	python/python-exitedevent.c \
+	python/python-eventregistry.c
 SUBDIR_PYTHON_DEPS =
 SUBDIR_PYTHON_LDFLAGS=
 SUBDIR_PYTHON_CFLAGS=
@@ -1958,12 +1972,41 @@ python-value.o: $(srcdir)/python/python-value.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-value.c
 	$(POSTCOMPILE)

+python-event.o: $(srcdir)/python/python-event.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-event.c
+	$(POSTCOMPILE)
+
+python-stopevent.o: $(srcdir)/python/python-stopevent.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-stopevent.c
+	$(POSTCOMPILE)
+
+python-signalstopevent.o: $(srcdir)/python/python-signalstopevent.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-signalstopevent.c
+	$(POSTCOMPILE)
+
+python-breakpointstopevent.o: $(srcdir)/python/python-breakpointstopevent.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-breakpointstopevent.c
+	$(POSTCOMPILE)
+
+python-continueevent.o: $(srcdir)/python/python-continueevent.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-continueevent.c
+	$(POSTCOMPILE)
+
+python-exitedevent.o: $(srcdir)/python/python-exitedevent.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-exitedevent.c
+	$(POSTCOMPILE)
+
+python-eventregistry.o: $(srcdir)/python/python-eventregistry.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-eventregistry.c
+	$(POSTCOMPILE)
+
 # All python library files, with the "python/lib" stripped off.
 # Note that we should only install files in the "gdb" module.
 PY_FILES = gdb/FrameIterator.py gdb/FrameWrapper.py gdb/command/alias.py \
     gdb/command/backtrace.py gdb/command/require.py \
     gdb/command/pahole.py gdb/command/upto.py gdb/command/__init__.py \
     gdb/command/ignore_errors.py gdb/command/save_breakpoints.py \
+    gdb/command/check_segfault.py gdb/command/test_events.py \
     gdb/function/caller_is.py gdb/function/in_scope.py \
     gdb/function/__init__.py gdb/backtrace.py gdb/__init__.py

diff --git a/gdb/python/python-breakpoint.c b/gdb/python/python-breakpoint.c
index afa9526..5e8bdba 100644
--- a/gdb/python/python-breakpoint.c
+++ b/gdb/python/python-breakpoint.c
@@ -31,9 +31,6 @@
 /* From breakpoint.c.  */
 extern struct breakpoint *breakpoint_chain;

-
-typedef struct breakpoint_object breakpoint_object;
-
 static PyTypeObject breakpoint_object_type;

 /* A dynamically allocated vector of breakpoint objects.  Each
@@ -54,18 +51,6 @@ static int bppy_live;
    constructor and the breakpoint-created hook function.  */
 static breakpoint_object *bppy_pending_object;

-struct breakpoint_object
-{
-  PyObject_HEAD
-
-  /* The breakpoint number according to gdb.  */
-  int number;
-
-  /* The gdb breakpoint object, or NULL if the breakpoint has been
-     deleted.  */
-  struct breakpoint *bp;
-};
-
 /* Evaluate to true if the breakpoint NUM is valid, false otherwise.  */
 #define BPPY_VALID_P(Num)			\
     ((Num) >= 0					\
@@ -455,6 +440,30 @@ bppy_new (PyTypeObject *subtype, PyObject *args,
PyObject *kwargs)
   return result;
 }

+/* Function to get the corresponding breakpoint object for the given
bpstats. */
+breakpoint_object *
+gdbpy_breakpoint_from_bpstats (struct bpstats *bs)
+{
+  int i, out = 0;
+  breakpoint_object *breakpoint = NULL;
+
+  if (bppy_live == 0)
+    return NULL;
+
+  for (i = 0; out < bppy_live; i++)
+    {
+      if (! bppy_breakpoints[i])
+	continue;
+
+      if (bs->breakpoint_at == bppy_breakpoints[i]->bp->loc)
+	breakpoint = bppy_breakpoints[i];
+
+      ++out;
+    }
+
+  return breakpoint;
+}
+
 \f

 /* Static function to return a tuple holding all breakpoints.  */
diff --git a/gdb/python/python-inferior.c b/gdb/python/python-inferior.c
index fc36550..5e80e91 100644
--- a/gdb/python/python-inferior.c
+++ b/gdb/python/python-inferior.c
@@ -26,6 +26,7 @@
 #include "python-internal.h"
 #include "arch-utils.h"
 #include "language.h"
+#include "gdb_signals.h"

 struct threadlist_entry {
   thread_object *thread_obj;
@@ -278,6 +279,71 @@ delete_thread_object (struct thread_info *tp, int ignore)
   PyGILState_Release (state);
 }

+static void
+python_on_normal_stop (struct bpstats *bs, int print_frame)
+{
+  PyGILState_STATE state;
+  char *stop_signal;
+
+  if (!find_thread_ptid (inferior_ptid))
+      return;
+
+  stop_signal = (char *) target_signal_to_name
(inferior_thread()->stop_signal);
+
+  state = PyGILState_Ensure ();
+
+  emit_stop_event (bs, stop_signal);
+
+  PyGILState_Release (state);
+}
+
+static void
+python_on_resume (ptid_t ptid)
+{
+  PyGILState_STATE state;
+
+  state = PyGILState_Ensure ();
+
+  emit_continue_event (ptid);
+
+  PyGILState_Release (state);
+}
+
+static void
+python_thread_exit (struct thread_info *tp, int ignore)
+{
+  PyGILState_STATE state;
+  LONGEST exitcode_val;
+  long long int *exit_code;
+  inferior_object *inf_obj;
+  thread_object *thread_obj;
+  struct threadlist_entry **entry;
+
+  inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid));
+  if (!inf_obj)
+    return;
+
+  /* Find thread entry in its inferior's thread_list. */
+  for (entry = &inf_obj->threads; *entry != NULL; entry = &(*entry)->next)
+    if ((*entry)->thread_obj->thread == tp)
+      break;
+
+  if (!*entry)
+    return;
+
+  thread_obj = (*entry)->thread_obj;
+
+  state = PyGILState_Ensure ();
+
+  if (get_internalvar_integer (lookup_internalvar ("_exitcode"),
&exitcode_val))
+    exit_code = &exitcode_val;
+
+  if (exit_code)
+    emit_exited_event (thread_obj, exit_code);
+
+  PyGILState_Release (state);
+}
+
 static PyObject *
 infpy_threads (PyObject *self, PyObject *args)
 {
@@ -779,6 +845,9 @@ gdbpy_initialize_inferior (void)
   observer_attach_inferior_exit (delete_inferior_object);
   observer_attach_new_thread (add_thread_object);
   observer_attach_thread_exit (delete_thread_object);
+  observer_attach_normal_stop (python_on_normal_stop);
+  observer_attach_target_resumed (python_on_resume);
+  observer_attach_thread_exit (python_thread_exit);

   if (PyType_Ready (&membuf_object_type) < 0)
     return;
diff --git a/gdb/python/python-infthread.c b/gdb/python/python-infthread.c
index 21e4eab..c8b1ff7 100644
--- a/gdb/python/python-infthread.c
+++ b/gdb/python/python-infthread.c
@@ -42,7 +42,7 @@ thread_object *
 create_thread_object (struct thread_info *tp)
 {
   thread_object *thread_obj;
-
+
   thread_obj = PyObject_New (thread_object, &thread_object_type);
   if (!thread_obj)
     return NULL;
@@ -51,6 +51,12 @@ create_thread_object (struct thread_info *tp)
   thread_obj->inf_obj = find_inferior_object (PIDGET (tp->ptid));
   Py_INCREF (thread_obj->inf_obj);

+  thread_obj->stop_eventregistry = create_eventregistry_object ();
+  thread_obj->breakpoint_stop_eventregistry = create_eventregistry_object ();
+  thread_obj->signal_stop_eventregistry = create_eventregistry_object ();
+  thread_obj->continue_eventregistry = create_eventregistry_object ();
+  thread_obj->exited_eventregistry = create_eventregistry_object ();
+
   return thread_obj;
 }

@@ -60,6 +66,11 @@ static void
 thpy_dealloc (PyObject *self)
 {
   Py_DECREF (((thread_object *) self)->inf_obj);
+  Py_DECREF (((thread_object *) self)->stop_eventregistry);
+  Py_DECREF (((thread_object *) self)->breakpoint_stop_eventregistry);
+  Py_DECREF (((thread_object *) self)->signal_stop_eventregistry);
+  Py_DECREF (((thread_object *) self)->continue_eventregistry);
+  Py_DECREF (((thread_object *) self)->exited_eventregistry);
   self->ob_type->tp_free (self);
 }

@@ -73,6 +84,65 @@ thpy_get_num (PyObject *self, void *closure)
   return PyLong_FromLong (thread_obj->thread->num);
 }

+static PyObject *
+thpy_get_stop_eventregistry (PyObject *self, void *closure)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  Py_INCREF (thread_obj->stop_eventregistry);
+
+  return (PyObject *) (thread_obj->stop_eventregistry);
+}
+
+static PyObject *
+thpy_get_breakpoint_stop_eventregistry (PyObject *self, void *closure)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  Py_INCREF (thread_obj->breakpoint_stop_eventregistry);
+
+  return (PyObject *) (thread_obj->breakpoint_stop_eventregistry);
+}
+
+static PyObject *
+thpy_get_signal_stop_eventregistry (PyObject *self, void *closure)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  Py_INCREF (thread_obj->signal_stop_eventregistry);
+
+  return (PyObject *) (thread_obj->signal_stop_eventregistry);
+}
+
+static PyObject *
+thpy_get_continue_eventregistry (PyObject *self, void *closure)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  Py_INCREF (thread_obj->continue_eventregistry);
+
+  return (PyObject *) (thread_obj->continue_eventregistry);
+}
+
+static PyObject *
+thpy_get_exited_eventregistry (PyObject *self, void *closure)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  Py_INCREF (thread_obj->exited_eventregistry);
+
+  return (PyObject *) (thread_obj->exited_eventregistry);
+}
 \f

 /* Implementation of Inferior.frames () -> (gdb.Frame, ...).
@@ -194,7 +264,7 @@ PyObject *
 gdbpy_selected_thread (PyObject *self, PyObject *args)
 {
   PyObject *thread_obj;
-
+
   thread_obj = (PyObject *) find_thread_object (inferior_ptid);
   if (thread_obj)
     {
@@ -223,6 +293,11 @@ gdbpy_initialize_thread (void)
 static PyGetSetDef thread_object_getset[] =
 {
   { "num", thpy_get_num, NULL, "ID of the thread, as assigned by GDB.", NULL },
+  { "stop_eventregistry", thpy_get_stop_eventregistry, NULL, "Stop
event registry object of the thread.", NULL },
+  { "breakpoint_stop_eventregistry",
thpy_get_breakpoint_stop_eventregistry, NULL, "Breakpoint stop event
registry object of the thread.", NULL },
+  { "signal_stop_eventregistry", thpy_get_signal_stop_eventregistry,
NULL, "Signal stop event registry object of the thread.", NULL },
+  { "continue_eventregistry", thpy_get_continue_eventregistry, NULL,
"Continue event registry object of the thread.", NULL },
+  { "exited_eventregistry", thpy_get_exited_eventregistry, NULL,
"Exited event registry object of the thread.", NULL },

   { NULL }
 };
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 47662d9..b72c59e 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -62,6 +62,7 @@ typedef int Py_ssize_t;
 #endif

 #include "command.h"
+#include "breakpoint.h"

 struct block;
 struct symbol;
@@ -73,6 +74,31 @@ extern PyObject *gdb_module;
 extern PyTypeObject block_object_type;
 extern PyTypeObject value_object_type;
 extern PyTypeObject symbol_object_type;
+extern PyTypeObject event_object_type;
+extern PyTypeObject stop_event_object_type;
+
+/* Used in python-breakpoint.c */
+typedef struct breakpoint_object breakpoint_object;
+
+struct breakpoint_object
+{
+  PyObject_HEAD
+
+  /* The breakpoint number according to gdb.  */
+  int number;
+
+  /* The gdb breakpoint object, or NULL if the breakpoint has been
+     deleted.  */
+  struct breakpoint *bp;
+};
+
+/* Used in python-eventregistry.c */
+typedef struct
+{
+  PyObject_HEAD
+
+  PyListObject *callbacks;
+} eventregistry_object;

 /* Used in python-inferior.c.  */
 typedef struct
@@ -82,10 +108,32 @@ typedef struct
   /* The thread we represent.  */
   struct thread_info *thread;

+  eventregistry_object *stop_eventregistry;
+  eventregistry_object *breakpoint_stop_eventregistry;
+  eventregistry_object *signal_stop_eventregistry;
+  eventregistry_object *continue_eventregistry;
+  eventregistry_object *exited_eventregistry;
+
   /* The Inferior object to which this thread belongs.  */
   PyObject *inf_obj;
 } thread_object;

+/* Used in python-event.c */
+typedef struct
+{
+  PyObject_HEAD
+
+  thread_object *inferior_thread;
+  PyStringObject *event_type;
+} event_object;
+
+/* Used in python-stopevent.c */
+typedef struct
+{
+  event_object event;
+  PyStringObject *stop_reason;
+} stop_event_object;
+
 PyObject *gdbpy_history (PyObject *self, PyObject *args);
 PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
 PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
@@ -107,6 +155,13 @@ PyObject *frame_info_to_frame_object (struct
frame_info *frame);
 thread_object *create_thread_object (struct thread_info *tp);
 thread_object *find_thread_object (ptid_t ptid);
 PyObject *find_inferior_object (int pid);
+eventregistry_object *create_eventregistry_object (void);
+breakpoint_object *gdbpy_breakpoint_from_bpstats (struct bpstats *bs);
+void emit_stop_event (struct bpstats *bs, const char *stop_signal);
+void emit_breakpoint_stop_event (struct bpstats *bs);
+void emit_signal_stop_event (const char *stop_signal);
+void emit_continue_event (ptid_t ptid);
+void emit_exited_event (thread_object *inferior_thread, long long int
*exit_code);

 PyObject *objfpy_get_printers (PyObject *, void *);

@@ -131,6 +186,13 @@ void gdbpy_initialize_objfile (void);
 void gdbpy_initialize_parameters (void);
 void gdbpy_initialize_thread (void);
 void gdbpy_initialize_inferior (void);
+void gdbpy_initialize_eventregistry (void);
+void gdbpy_initialize_event (void);
+void gdbpy_initialize_stop_event (void);
+void gdbpy_initialize_signal_stop_event (void);
+void gdbpy_initialize_breakpoint_stop_event (void);
+void gdbpy_initialize_continue_event (void);
+void gdbpy_initialize_exited_event (void);

 struct cleanup *make_cleanup_py_decref (PyObject *py);

diff --git a/gdb/python/python.c b/gdb/python/python.c
index 5a2a9ae..0b1ae78 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -918,6 +918,13 @@ Enables or disables auto-loading of Python code
when an object is opened."),
   gdbpy_initialize_thread ();
   gdbpy_initialize_inferior ();
   gdbpy_initialize_events ();
+  gdbpy_initialize_eventregistry ();
+  gdbpy_initialize_event ();
+  gdbpy_initialize_stop_event ();
+  gdbpy_initialize_signal_stop_event ();
+  gdbpy_initialize_breakpoint_stop_event ();
+  gdbpy_initialize_continue_event ();
+  gdbpy_initialize_exited_event ();

   PyRun_SimpleString ("import gdb");
   PyRun_SimpleString ("gdb.pretty_printers = []");

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [RFC][1/5] Changes to the current branch
  2009-08-23 15:34 [RFC][1/5] Changes to the current branch Oguz Kayral
@ 2009-09-21 21:52 ` Tom Tromey
  0 siblings, 0 replies; 2+ messages in thread
From: Tom Tromey @ 2009-09-21 21:52 UTC (permalink / raw)
  To: Oguz Kayral; +Cc: archer

Oguz> diff --git a/gdb/python/python-breakpoint.c b/gdb/python/python-breakpoint.c
Oguz> -struct breakpoint_object
Oguz> -{
Oguz> -  PyObject_HEAD
Oguz> -
Oguz> -  /* The breakpoint number according to gdb.  */
Oguz> -  int number;
Oguz> -
Oguz> -  /* The gdb breakpoint object, or NULL if the breakpoint has been
Oguz> -     deleted.  */
Oguz> -  struct breakpoint *bp;
Oguz> -};

It seems to me that this type could still be private to the breakpoint
code.  I think it is generally preferable to do this and use accessor
functions.

Oguz> +static void
Oguz> +python_on_normal_stop (struct bpstats *bs, int print_frame)
Oguz> +{
[...]
Oguz> +  state = PyGILState_Ensure ();

We use cleanups for acquiring the GIL now.

Oguz> +static void
Oguz> +python_thread_exit (struct thread_info *tp, int ignore)
Oguz> +{
[...]
Oguz> +  long long int *exit_code;

You can't use long long; just use LONGEST instead.

Oguz> +  { "stop_eventregistry", thpy_get_stop_eventregistry, NULL, "Stop
Oguz> event registry object of the thread.", NULL },

I'm not so sure about the names ending in "registry".
"stop_event" seems just as clear to me.

Tom

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-09-21 21:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-23 15:34 [RFC][1/5] Changes to the current branch Oguz Kayral
2009-09-21 21:52 ` Tom Tromey

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).