aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorHui Zhu <teawater@gmail.com>2011-02-05 05:27:23 +0000
committerHui Zhu <teawater@gmail.com>2011-02-05 05:27:23 +0000
commitc17a9e46882cb057d7e1d150ac9974425dc55e03 (patch)
treefbd60a7c8eae30e33e904fe1877671b2ba378551 /gdb/python
parent55382fb77a791c87165d4a3f65a53dc00c80959c (diff)
downloadgdb-c17a9e46882cb057d7e1d150ac9974425dc55e03.zip
gdb-c17a9e46882cb057d7e1d150ac9974425dc55e03.tar.gz
gdb-c17a9e46882cb057d7e1d150ac9974425dc55e03.tar.bz2
Add the file that prev commit forget.
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-bpevent.c52
-rw-r--r--gdb/python/py-continueevent.c53
-rw-r--r--gdb/python/py-event.c175
-rw-r--r--gdb/python/py-event.h121
-rw-r--r--gdb/python/py-events.h59
-rw-r--r--gdb/python/py-evtregistry.c170
-rw-r--r--gdb/python/py-evts.c71
-rw-r--r--gdb/python/py-exitedevent.c71
-rw-r--r--gdb/python/py-signalevent.c53
-rw-r--r--gdb/python/py-stopevent.c92
-rw-r--r--gdb/python/py-stopevent.h37
-rw-r--r--gdb/python/py-threadevent.c78
12 files changed, 1032 insertions, 0 deletions
diff --git a/gdb/python/py-bpevent.c b/gdb/python/py-bpevent.c
new file mode 100644
index 0000000..c7f7965
--- /dev/null
+++ b/gdb/python/py-bpevent.c
@@ -0,0 +1,52 @@
+/* Python interface to inferior breakpoint stop events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "py-stopevent.h"
+
+static PyTypeObject breakpoint_event_object_type;
+
+/* Create and initialize a BreakpointEvent object. */
+
+PyObject *
+create_breakpoint_event_object (PyObject *breakpoint)
+{
+ PyObject *breakpoint_event_obj =
+ create_stop_event_object (&breakpoint_event_object_type);
+
+ if (!breakpoint_event_obj)
+ goto fail;
+
+ if (evpy_add_attribute (breakpoint_event_obj,
+ "breakpoint",
+ breakpoint) < 0)
+ goto fail;
+
+ return breakpoint_event_obj;
+
+ fail:
+ Py_XDECREF (breakpoint_event_obj);
+ return NULL;
+}
+
+GDBPY_NEW_EVENT_TYPE (breakpoint,
+ "gdb.BreakpointEvent",
+ "BreakpointEvent",
+ "GDB breakpoint stop event object",
+ stop_event_object_type,
+ static);
diff --git a/gdb/python/py-continueevent.c b/gdb/python/py-continueevent.c
new file mode 100644
index 0000000..1338ba6
--- /dev/null
+++ b/gdb/python/py-continueevent.c
@@ -0,0 +1,53 @@
+/* Python interface to inferior continue events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "py-event.h"
+
+static PyTypeObject continue_event_object_type;
+
+PyObject *
+create_continue_event_object (void)
+{
+ return create_thread_event_object (&continue_event_object_type);
+}
+
+/* Callback function which notifies observers when a continue event occurs.
+ This function will create a new Python continue event object.
+ Return -1 if emit fails. */
+
+int
+emit_continue_event (ptid_t ptid)
+{
+ PyObject *event;
+
+ if (evregpy_no_listeners_p (gdb_py_events.cont))
+ return 0;
+
+ event = create_continue_event_object ();
+ if (event)
+ return evpy_emit_event (event, gdb_py_events.cont);
+ return -1;
+}
+
+GDBPY_NEW_EVENT_TYPE (continue,
+ "gdb.ContinueEvent",
+ "ContinueEvent",
+ "GDB continue event object",
+ thread_event_object_type,
+ static);
diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c
new file mode 100644
index 0000000..88f8db6
--- /dev/null
+++ b/gdb/python/py-event.c
@@ -0,0 +1,175 @@
+/* Python interface to inferior events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "py-event.h"
+
+void
+evpy_dealloc (PyObject *self)
+{
+ Py_XDECREF (((event_object *) self)->dict);
+ self->ob_type->tp_free (self);
+}
+
+PyObject *
+create_event_object (PyTypeObject *py_type)
+{
+ event_object *event_obj;
+
+ event_obj = PyObject_New (event_object, py_type);
+ if (!event_obj)
+ goto fail;
+
+ event_obj->dict = PyDict_New ();
+ if (!event_obj->dict)
+ goto fail;
+
+ return (PyObject*) event_obj;
+
+ fail:
+ Py_XDECREF (event_obj);
+ return NULL;
+}
+
+/* Add the attribute ATTR to the event object EVENT. In
+ python this attribute will be accessible by the name NAME.
+ returns 0 if the operation succeeds and -1 otherwise. */
+
+int
+evpy_add_attribute (PyObject *event, char *name, PyObject *attr)
+{
+ return PyObject_SetAttrString (event, name, attr);
+}
+
+/* Initialize the Python event code. */
+
+void
+gdbpy_initialize_event (void)
+{
+ gdbpy_initialize_event_generic (&event_object_type,
+ "Event");
+}
+
+/* Initialize the given event type. If BASE is not NULL it will
+ be set as the types base.
+ Returns 0 if initialization was successful -1 otherwise. */
+
+int
+gdbpy_initialize_event_generic (PyTypeObject *type,
+ char *name)
+{
+ if (PyType_Ready (type) < 0)
+ goto fail;
+
+ Py_INCREF (type);
+ if (PyModule_AddObject (gdb_module, name, (PyObject *) type) < 0)
+ goto fail;
+
+ return 0;
+
+ fail:
+ Py_XDECREF (type);
+ return -1;
+}
+
+
+/* Notify the list of listens that the given EVENT has occurred.
+ returns 0 if emit is successful -1 otherwise. */
+
+int
+evpy_emit_event (PyObject *event,
+ eventregistry_object *registry)
+{
+ PyObject *callback_list_copy = NULL;
+ Py_ssize_t i;
+
+ /* Create a copy of call back list and use that for
+ notifying listeners to avoid skipping callbacks
+ in the case of a callback being disconnected during
+ a notification. */
+ callback_list_copy = PySequence_List (registry->callbacks);
+ if (!callback_list_copy)
+ goto fail;
+
+ for (i = 0; i < PyList_Size (callback_list_copy); i++)
+ {
+ PyObject *func = PyList_GetItem (callback_list_copy, i);
+
+ if (func == NULL)
+ goto fail;
+
+ if (!PyObject_CallFunctionObjArgs (func, event, NULL))
+ {
+ /* Print the trace here, but keep going -- we want to try to
+ call all of the callbacks even if one is broken. */
+ gdbpy_print_stack ();
+ }
+ }
+
+ Py_XDECREF (callback_list_copy);
+ Py_XDECREF (event);
+ return 0;
+
+ fail:
+ gdbpy_print_stack ();
+ Py_XDECREF (callback_list_copy);
+ Py_XDECREF (event);
+ return -1;
+}
+
+PyTypeObject event_object_type =
+{
+ PyObject_HEAD_INIT (NULL)
+ 0, /* ob_size */
+ "gdb.Event", /* tp_name */
+ sizeof (event_object), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ evpy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "GDB event object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof (event_object, dict), /* tp_dictoffset */
+ 0, /* tp_init */
+ 0 /* tp_alloc */
+};
diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h
new file mode 100644
index 0000000..bc95521
--- /dev/null
+++ b/gdb/python/py-event.h
@@ -0,0 +1,121 @@
+/* Python interface to inferior events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_PY_EVENT_H
+#define GDB_PY_EVENT_H
+
+#include "defs.h"
+#include "py-events.h"
+#include "command.h"
+#include "python-internal.h"
+#include "inferior.h"
+
+/* This macro creates the following functions:
+
+ gdbpy_initialize_{NAME}_event
+ Used to add the newly created event type to the gdb module.
+
+ and the python type data structure for the event:
+
+ struct PyTypeObject {NAME}_event_object_type
+
+ NAME is the name of the event.
+ PY_PATH is a string representing the module and python name of
+ the event.
+ PY_NAME a string representing what the event should be called in
+ python.
+ DOC Python documentation for the new event type
+ BASE the base event for this event usually just event_object_type.
+ QUAL qualification for the create event usually 'static'
+*/
+
+#define GDBPY_NEW_EVENT_TYPE(name, py_path, py_name, doc, base, qual) \
+\
+ qual PyTypeObject name##_event_object_type = \
+ { \
+ PyObject_HEAD_INIT (NULL) \
+ 0, /* ob_size */ \
+ py_path, /* tp_name */ \
+ sizeof (event_object), /* tp_basicsize */ \
+ 0, /* tp_itemsize */ \
+ evpy_dealloc, /* tp_dealloc */ \
+ 0, /* tp_print */ \
+ 0, /* tp_getattr */ \
+ 0, /* tp_setattr */ \
+ 0, /* tp_compare */ \
+ 0, /* tp_repr */ \
+ 0, /* tp_as_number */ \
+ 0, /* tp_as_sequence */ \
+ 0, /* tp_as_mapping */ \
+ 0, /* tp_hash */ \
+ 0, /* tp_call */ \
+ 0, /* tp_str */ \
+ 0, /* tp_getattro */ \
+ 0, /* tp_setattro */ \
+ 0, /* tp_as_buffer */ \
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ \
+ doc, /* tp_doc */ \
+ 0, /* tp_traverse */ \
+ 0, /* tp_clear */ \
+ 0, /* tp_richcompare */ \
+ 0, /* tp_weaklistoffset */ \
+ 0, /* tp_iter */ \
+ 0, /* tp_iternext */ \
+ 0, /* tp_methods */ \
+ 0, /* tp_members */ \
+ 0, /* tp_getset */ \
+ &base, /* tp_base */ \
+ 0, /* tp_dict */ \
+ 0, /* tp_descr_get */ \
+ 0, /* tp_descr_set */ \
+ 0, /* tp_dictoffset */ \
+ 0, /* tp_init */ \
+ 0 /* tp_alloc */ \
+ }; \
+\
+void \
+gdbpy_initialize_##name##_event (void) \
+{ \
+ gdbpy_initialize_event_generic (&name##_event_object_type, \
+ py_name); \
+}
+
+typedef struct
+{
+ PyObject_HEAD
+
+ PyObject *dict;
+} event_object;
+
+extern int emit_continue_event (ptid_t ptid);
+extern int emit_exited_event (LONGEST exit_code);
+
+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 void evpy_dealloc (PyObject *self);
+extern int evpy_add_attribute (PyObject *event,
+ char *name, PyObject *attr);
+int gdbpy_initialize_event_generic (PyTypeObject *type, char *name);
+
+
+#endif /* GDB_PY_EVENT_H */
diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h
new file mode 100644
index 0000000..6d4dae5
--- /dev/null
+++ b/gdb/python/py-events.h
@@ -0,0 +1,59 @@
+/* Python interface to inferior events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_PY_EVENTS_H
+#define GDB_PY_EVENTS_H
+
+#include "defs.h"
+#include "command.h"
+#include "python-internal.h"
+#include "inferior.h"
+
+extern PyTypeObject thread_event_object_type;
+
+/* Stores a list of objects to be notified when the event for which this
+ registry tracks occurs. */
+
+typedef struct
+{
+ PyObject_HEAD
+
+ PyObject *callbacks;
+} eventregistry_object;
+
+/* Struct holding references to event registries both in python and c.
+ This is meant to be a singleton. */
+
+typedef struct
+{
+ eventregistry_object *stop;
+ eventregistry_object *cont;
+ eventregistry_object *exited;
+
+ PyObject *module;
+
+} events_object;
+
+/* Python events singleton. */
+events_object gdb_py_events;
+
+extern eventregistry_object *create_eventregistry_object (void);
+extern int evregpy_no_listeners_p (eventregistry_object *registry);
+
+#endif /* GDB_PY_EVENTS_H */
diff --git a/gdb/python/py-evtregistry.c b/gdb/python/py-evtregistry.c
new file mode 100644
index 0000000..e1b4346
--- /dev/null
+++ b/gdb/python/py-evtregistry.c
@@ -0,0 +1,170 @@
+/* Python interface to inferior thread event registries.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "command.h"
+#include "py-events.h"
+
+static PyTypeObject eventregistry_object_type;
+
+/* Implementation of EventRegistry.connect () -> NULL.
+ Add FUNCTION to the list of listeners. */
+
+static PyObject *
+evregpy_connect (PyObject *self, PyObject *function)
+{
+ PyObject *func;
+ PyObject *callback_list = (((eventregistry_object *) self)->callbacks);
+
+ if (!PyArg_ParseTuple (function, "O", &func))
+ return NULL;
+
+ if (!PyCallable_Check (func))
+ {
+ PyErr_SetString (PyExc_RuntimeError, "Function is not callable");
+ return NULL;
+ }
+
+ if (PyList_Append (callback_list, func) < 0)
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+/* Implementation of EventRegistry.disconnect () -> NULL.
+ Remove FUNCTION from the list of listeners. */
+
+static PyObject *
+evregpy_disconnect (PyObject *self, PyObject *function)
+{
+ PyObject *func;
+ int index;
+ PyObject *callback_list = (((eventregistry_object *) self)->callbacks);
+
+ if (!PyArg_ParseTuple (function, "O", &func))
+ return NULL;
+
+ index = PySequence_Index (callback_list, func);
+ if (index < 0)
+ Py_RETURN_NONE;
+
+ if (PySequence_DelItem (callback_list, index) < 0)
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+/* Create a new event registry. This function uses PyObject_New
+ and therefore returns a new reference that callers must handle. */
+
+eventregistry_object *
+create_eventregistry_object (void)
+{
+ eventregistry_object *eventregistry_obj;
+
+ eventregistry_obj = PyObject_New (eventregistry_object,
+ &eventregistry_object_type);
+
+ if (!eventregistry_obj)
+ return NULL;
+
+ eventregistry_obj->callbacks = PyList_New (0);
+ if (!eventregistry_obj->callbacks)
+ return NULL;
+
+ return eventregistry_obj;
+}
+
+static void
+evregpy_dealloc (PyObject *self)
+{
+ Py_XDECREF (((eventregistry_object *) self)->callbacks);
+ self->ob_type->tp_free (self);
+}
+
+/* Initialize the Python event registry code. */
+
+void
+gdbpy_initialize_eventregistry (void)
+{
+ if (PyType_Ready (&eventregistry_object_type) < 0)
+ return;
+
+ Py_INCREF (&eventregistry_object_type);
+ PyModule_AddObject (gdb_module, "EventRegistry",
+ (PyObject *) &eventregistry_object_type);
+}
+
+/* Retern the number of listeners currently connected to this
+ registry. */
+
+int
+evregpy_no_listeners_p (eventregistry_object *registry)
+{
+ return PyList_Size (registry->callbacks) == 0;
+}
+
+static PyMethodDef eventregistry_object_methods[] =
+{
+ { "connect", evregpy_connect, METH_VARARGS, "Add function" },
+ { "disconnect", evregpy_disconnect, METH_VARARGS, "Remove function" },
+ { NULL } /* Sentinel. */
+};
+
+static PyTypeObject eventregistry_object_type =
+{
+ PyObject_HEAD_INIT (NULL)
+ 0, /* ob_size */
+ "gdb.EventRegistry", /* tp_name */
+ sizeof (eventregistry_object), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ evregpy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ "GDB event registry object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ eventregistry_object_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0 /* tp_alloc */
+};
diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c
new file mode 100644
index 0000000..446b934
--- /dev/null
+++ b/gdb/python/py-evts.c
@@ -0,0 +1,71 @@
+/* Python interface to inferior events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "py-events.h"
+
+/* Initialize python events. */
+
+static int
+add_new_registry (eventregistry_object **registryp, char *name)
+{
+ *registryp = create_eventregistry_object ();
+
+ if (*registryp == NULL)
+ goto fail;
+
+ if (PyModule_AddObject (gdb_py_events.module,
+ name,
+ (PyObject *)(*registryp)) < 0)
+ goto fail;
+
+ return 0;
+
+ fail:
+ Py_XDECREF (*registryp);
+ return -1;
+}
+
+void
+gdbpy_initialize_py_events ()
+{
+ gdb_py_events.module = Py_InitModule ("events", NULL);
+
+ if (!gdb_py_events.module)
+ goto fail;
+
+ if (add_new_registry (&gdb_py_events.stop, "stop") < 0)
+ goto fail;
+
+ if (add_new_registry (&gdb_py_events.cont, "cont") < 0)
+ goto fail;
+
+ if (add_new_registry (&gdb_py_events.exited, "exited") < 0)
+ goto fail;
+
+ Py_INCREF (gdb_py_events.module);
+ if (PyModule_AddObject (gdb_module,
+ "events",
+ (PyObject *) gdb_py_events.module) < 0)
+ goto fail;
+
+ return;
+
+ fail:
+ gdbpy_print_stack ();
+}
diff --git a/gdb/python/py-exitedevent.c b/gdb/python/py-exitedevent.c
new file mode 100644
index 0000000..457a4fe
--- /dev/null
+++ b/gdb/python/py-exitedevent.c
@@ -0,0 +1,71 @@
+/* Python interface to inferior exit events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "py-event.h"
+
+static PyTypeObject exited_event_object_type;
+
+PyObject *
+create_exited_event_object (LONGEST exit_code)
+{
+ PyObject *exited_event;
+
+ exited_event = create_event_object (&exited_event_object_type);
+
+ if (!exited_event)
+ goto fail;
+
+ if (evpy_add_attribute (exited_event,
+ "exit_code",
+ PyLong_FromLongLong (exit_code)) < 0)
+ goto fail;
+
+ return exited_event;
+
+ fail:
+ Py_XDECREF (exited_event);
+ return NULL;
+}
+
+/* Callback that is used when an exit event occurs. This function
+ will create a new Python exited event object. */
+
+int
+emit_exited_event (LONGEST exit_code)
+{
+ PyObject *event;
+
+ if (evregpy_no_listeners_p (gdb_py_events.exited))
+ return 0;
+
+ event = create_exited_event_object (exit_code);
+
+ if (event)
+ return evpy_emit_event (event, gdb_py_events.exited);
+
+ return -1;
+}
+
+
+GDBPY_NEW_EVENT_TYPE (exited,
+ "gdb.ExitedEvent",
+ "ExitedEvent",
+ "GDB exited event object",
+ event_object_type,
+ static);
diff --git a/gdb/python/py-signalevent.c b/gdb/python/py-signalevent.c
new file mode 100644
index 0000000..3d7ce32
--- /dev/null
+++ b/gdb/python/py-signalevent.c
@@ -0,0 +1,53 @@
+/* Python interface to inferior signal stop events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "py-stopevent.h"
+
+static PyTypeObject signal_event_object_type;
+
+PyObject *
+create_signal_event_object (enum target_signal stop_signal)
+{
+ const char *signal_name;
+ PyObject *signal_event_obj =
+ create_stop_event_object (&signal_event_object_type);
+
+ if (!signal_event_obj)
+ goto fail;
+
+ signal_name = target_signal_to_name (stop_signal);
+
+ if (evpy_add_attribute (signal_event_obj,
+ "stop_signal",
+ PyString_FromString (signal_name)) < 0)
+ goto fail;
+
+ return signal_event_obj;
+
+ fail:
+ Py_XDECREF (signal_event_obj);
+ return NULL;
+}
+
+GDBPY_NEW_EVENT_TYPE (signal,
+ "gdb.SignalEvent",
+ "SignalEvent",
+ "GDB signal event object",
+ stop_event_object_type,
+ static);
diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c
new file mode 100644
index 0000000..122fe6b
--- /dev/null
+++ b/gdb/python/py-stopevent.c
@@ -0,0 +1,92 @@
+/* Python interface to inferior stop events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "py-stopevent.h"
+
+PyObject *
+create_stop_event_object (PyTypeObject *py_type)
+{
+ PyObject *stop_event_obj = create_thread_event_object (py_type);
+
+ if (!stop_event_obj)
+ goto fail;
+
+ return stop_event_obj;
+
+ fail:
+ Py_XDECREF (stop_event_obj);
+ return NULL;
+}
+
+/* Callback observers when a stop event occurs. This function will create a
+ new Python stop event object. If only a specific thread is stopped the
+ thread object of the event will be set to that thread. Otherwise, if all
+ threads are stopped thread object will be set to None.
+ return 0 if the event was created and emitted successfully otherwise
+ returns -1. */
+
+int
+emit_stop_event (struct bpstats *bs, enum target_signal stop_signal)
+{
+ PyObject *stop_event_obj = NULL; /* Appease GCC warning. */
+
+ if (evregpy_no_listeners_p (gdb_py_events.stop))
+ return 0;
+
+ if (bs && bs->breakpoint_at
+ && bs->breakpoint_at->py_bp_object)
+ {
+ stop_event_obj = create_breakpoint_event_object ((PyObject *) bs
+ ->breakpoint_at
+ ->py_bp_object);
+ if (!stop_event_obj)
+ goto fail;
+ }
+
+ /* Check if the signal is "Signal 0" or "Trace/breakpoint trap". */
+ if (stop_signal != TARGET_SIGNAL_0
+ && stop_signal != TARGET_SIGNAL_TRAP)
+ {
+ stop_event_obj =
+ create_signal_event_object (stop_signal);
+ if (!stop_event_obj)
+ goto fail;
+ }
+
+ /* If all fails emit an unknown stop event. All event types should
+ be known and this should eventually be unused. */
+ if (!stop_event_obj)
+ {
+ stop_event_obj = create_stop_event_object (&stop_event_object_type);
+ if (!stop_event_obj)
+ goto fail;
+ }
+
+ return evpy_emit_event (stop_event_obj, gdb_py_events.stop);
+
+ fail:
+ return -1;
+}
+
+GDBPY_NEW_EVENT_TYPE (stop,
+ "gdb.StopEvent",
+ "StopEvent",
+ "GDB stop event object",
+ thread_event_object_type,
+ /*no qual*/);
diff --git a/gdb/python/py-stopevent.h b/gdb/python/py-stopevent.h
new file mode 100644
index 0000000..690cbbd
--- /dev/null
+++ b/gdb/python/py-stopevent.h
@@ -0,0 +1,37 @@
+/* Python interface to inferior events.
+
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_PY_STOPEVENT_H
+#define GDB_PY_STOPEVENT_H
+
+#include "py-event.h"
+
+extern PyObject *create_stop_event_object (PyTypeObject *py_type);
+extern void stop_evpy_dealloc (PyObject *self);
+
+extern int emit_stop_event (struct bpstats *bs,
+ enum target_signal stop_signal);
+
+extern PyObject *
+create_breakpoint_event_object (PyObject *breakpoint);
+
+extern PyObject *
+create_signal_event_object (enum target_signal stop_signal);
+
+#endif /* GDB_PY_STOPEVENT_H */
diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c
new file mode 100644
index 0000000..7963412
--- /dev/null
+++ b/gdb/python/py-threadevent.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "py-event.h"
+
+/* thread events can either be thread specific or process wide. If gdb is
+ running in non-stop mode then the event is thread specific, otherwise
+ it is process wide.
+ This function returns the currently stopped thread in non-stop mode and
+ Py_None otherwise. */
+
+static PyObject *
+get_event_thread (void)
+{
+ PyObject *thread = NULL;
+
+ if (non_stop)
+ thread = (PyObject *) find_thread_object (inferior_ptid);
+ else
+ thread = Py_None;
+
+ if (!thread)
+ {
+ PyErr_SetString (PyExc_RuntimeError, "Could not find event thread");
+ return NULL;
+ }
+
+ Py_INCREF (thread);
+
+ return thread;
+}
+
+PyObject *
+create_thread_event_object (PyTypeObject *py_type)
+{
+ PyObject *thread = NULL;
+ PyObject *thread_event_obj = NULL;
+
+ thread_event_obj = create_event_object (py_type);
+ if (!thread_event_obj)
+ goto fail;
+
+ thread = get_event_thread ();
+ if (!thread)
+ goto fail;
+
+ if (evpy_add_attribute (thread_event_obj,
+ "inferior_thread",
+ thread) < 0)
+ goto fail;
+
+ return thread_event_obj;
+
+ fail:
+ Py_XDECREF (thread_event_obj);
+ return NULL;
+}
+
+GDBPY_NEW_EVENT_TYPE (thread,
+ "gdb.ThreadEvent",
+ "ThreadEvent",
+ "GDB thread event object",
+ event_object_type,
+ /*no qual*/);