From: Oguz Kayral <oguzkayral@gmail.com>
To: archer@sourceware.org
Subject: [RFC][1/5] Changes to the current branch
Date: Sun, 23 Aug 2009 15:34:00 -0000 [thread overview]
Message-ID: <36a35d480908230834n73393daduc92857e82aa2f234@mail.gmail.com> (raw)
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 = []");
next reply other threads:[~2009-08-23 15:34 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-23 15:34 Oguz Kayral [this message]
2009-09-21 21:52 ` Tom Tromey
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=36a35d480908230834n73393daduc92857e82aa2f234@mail.gmail.com \
--to=oguzkayral@gmail.com \
--cc=archer@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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).