Add the file that prev commit forget.
This commit is contained in:
parent
55382fb77a
commit
c17a9e4688
8
gdb/NEWS
8
gdb/NEWS
@ -70,6 +70,14 @@
|
||||
- gdb.events.exited Inferior exited event.
|
||||
- gdb.events.stop Signal received, and Breakpoint hit events.
|
||||
|
||||
** Python Support for Inferior events.
|
||||
Python scripts can add observers to be notified of events
|
||||
occurring the in process being debugged.
|
||||
The following events are currently supported:
|
||||
- gdb.events.cont Continue event.
|
||||
- gdb.events.exited Inferior exited event.
|
||||
- gdb.events.stop Signal received, and Breakpoint hit events.
|
||||
|
||||
* C++ Improvements:
|
||||
|
||||
** GDB now puts template parameters in scope when debugging in an
|
||||
|
52
gdb/python/py-bpevent.c
Normal file
52
gdb/python/py-bpevent.c
Normal file
@ -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);
|
53
gdb/python/py-continueevent.c
Normal file
53
gdb/python/py-continueevent.c
Normal file
@ -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);
|
175
gdb/python/py-event.c
Normal file
175
gdb/python/py-event.c
Normal file
@ -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 */
|
||||
};
|
121
gdb/python/py-event.h
Normal file
121
gdb/python/py-event.h
Normal file
@ -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 */
|
59
gdb/python/py-events.h
Normal file
59
gdb/python/py-events.h
Normal file
@ -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 */
|
170
gdb/python/py-evtregistry.c
Normal file
170
gdb/python/py-evtregistry.c
Normal file
@ -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 */
|
||||
};
|
71
gdb/python/py-evts.c
Normal file
71
gdb/python/py-evts.c
Normal file
@ -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 ();
|
||||
}
|
71
gdb/python/py-exitedevent.c
Normal file
71
gdb/python/py-exitedevent.c
Normal file
@ -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);
|
53
gdb/python/py-signalevent.c
Normal file
53
gdb/python/py-signalevent.c
Normal file
@ -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);
|
92
gdb/python/py-stopevent.c
Normal file
92
gdb/python/py-stopevent.c
Normal file
@ -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*/);
|
37
gdb/python/py-stopevent.h
Normal file
37
gdb/python/py-stopevent.h
Normal file
@ -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 */
|
78
gdb/python/py-threadevent.c
Normal file
78
gdb/python/py-threadevent.c
Normal file
@ -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*/);
|
29
gdb/testsuite/gdb.python/py-events.c
Normal file
29
gdb/testsuite/gdb.python/py-events.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
int second(){
|
||||
return 12;
|
||||
}
|
||||
|
||||
int first(){
|
||||
return second();
|
||||
}
|
||||
|
||||
int main (){
|
||||
return first();
|
||||
}
|
59
gdb/testsuite/gdb.python/py-events.exp
Normal file
59
gdb/testsuite/gdb.python/py-events.exp
Normal file
@ -0,0 +1,59 @@
|
||||
# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# This file is part of the GDB testsuite. It tests Python-based
|
||||
# pretty-printing for the CLI.
|
||||
|
||||
# Skip all tests if Python scripting is not enabled.
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
load_lib gdb-python.exp
|
||||
|
||||
set testfile "py-events"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
set pyfile ${srcdir}/${subdir}/${testfile}.py
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if { [skip_python_tests] } { continue }
|
||||
|
||||
gdb_test_no_output "python execfile ('${pyfile}')" ""
|
||||
|
||||
if ![runto_main ] then {
|
||||
fail "Can't run to main"
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_test "Test_Events" "Event testers registered."
|
||||
|
||||
gdb_breakpoint "first"
|
||||
|
||||
# Test continue event and breakpoint stop event
|
||||
gdb_test "continue" ".*event type: continue.*
|
||||
.*event type: stop.*
|
||||
.*stop reason: breakpoint.*
|
||||
.*breakpoint number: 2.*
|
||||
all threads stopped"
|
||||
|
||||
#test exited event.
|
||||
gdb_test "continue" ".*event type: continue.*
|
||||
.*event type: exit.*
|
||||
.*exit code: 12.*"
|
64
gdb/testsuite/gdb.python/py-events.py
Normal file
64
gdb/testsuite/gdb.python/py-events.py
Normal file
@ -0,0 +1,64 @@
|
||||
# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# This file is part of the GDB testsuite. It tests python pretty
|
||||
# printers.
|
||||
import gdb
|
||||
|
||||
def signal_stop_handler (event):
|
||||
if (isinstance (event, gdb.StopEvent)):
|
||||
print "event type: stop"
|
||||
if (isinstance (event, gdb.SignalEvent)):
|
||||
print "stop reason: signal"
|
||||
print "stop signal: %s" % (event.stop_signal)
|
||||
if ( event.inferior_thread is not None) :
|
||||
print "thread num: %s" % (event.inferior_thread.num);
|
||||
|
||||
def breakpoint_stop_handler (event):
|
||||
if (isinstance (event, gdb.StopEvent)):
|
||||
print "event type: stop"
|
||||
if (isinstance (event, gdb.BreakpointEvent)):
|
||||
print "stop reason: breakpoint"
|
||||
print "breakpoint number: %s" % (event.breakpoint.number)
|
||||
if ( event.inferior_thread is not None) :
|
||||
print "thread num: %s" % (event.inferior_thread.num);
|
||||
else:
|
||||
print "all threads stopped"
|
||||
|
||||
def exit_handler (event):
|
||||
if (isinstance (event, gdb.ExitedEvent)):
|
||||
print "event type: exit"
|
||||
print "exit code: %d" % (event.exit_code)
|
||||
|
||||
def continue_handler (event):
|
||||
if (isinstance (event, gdb.ContinueEvent)):
|
||||
print "event type: continue"
|
||||
if ( event.inferior_thread is not None) :
|
||||
print "thread num: %s" % (event.inferior_thread.num);
|
||||
|
||||
class test_events (gdb.Command):
|
||||
"""Test events."""
|
||||
|
||||
def __init__ (self):
|
||||
gdb.Command.__init__ (self, "test_events", gdb.COMMAND_STACK)
|
||||
|
||||
def invoke (self, arg, from_tty):
|
||||
gdb.events.stop.connect (signal_stop_handler)
|
||||
gdb.events.stop.connect (breakpoint_stop_handler)
|
||||
gdb.events.exited.connect (exit_handler)
|
||||
gdb.events.cont.connect (continue_handler)
|
||||
print "Event testers registered."
|
||||
|
||||
test_events ()
|
55
gdb/testsuite/gdb.python/py-evthreads.c
Normal file
55
gdb/testsuite/gdb.python/py-evthreads.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
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 <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_t thread2_id;
|
||||
pthread_t thread3_id;
|
||||
|
||||
void* thread3 (void* d)
|
||||
{
|
||||
int count3 = 0;
|
||||
count3++;
|
||||
|
||||
int *bad;
|
||||
*bad = 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* thread2 (void* d)
|
||||
{
|
||||
int count2 = 0;
|
||||
count2++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (){
|
||||
|
||||
pthread_create (&thread2_id, NULL, thread2, NULL);
|
||||
pthread_create (&thread3_id, NULL, thread3, NULL);
|
||||
|
||||
int count1 = 0; // stop1
|
||||
count1++;
|
||||
|
||||
pthread_join (thread2_id, NULL);
|
||||
pthread_join (thread3_id, NULL);
|
||||
return 12;
|
||||
}
|
119
gdb/testsuite/gdb.python/py-evthreads.exp
Normal file
119
gdb/testsuite/gdb.python/py-evthreads.exp
Normal file
@ -0,0 +1,119 @@
|
||||
# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
# 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/>.
|
||||
|
||||
# This file is part of the GDB testsuite. It tests Python-based
|
||||
# pretty-printing for the CLI.
|
||||
|
||||
# Skip all tests if Python scripting is not enabled.
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
load_lib gdb-python.exp
|
||||
|
||||
set testfile "py-evthreads"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
set pyfile ${srcdir}/${subdir}/py-events.py
|
||||
|
||||
gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug nowarnings}
|
||||
clean_restart $testfile
|
||||
|
||||
if { [skip_python_tests] } { continue }
|
||||
|
||||
gdb_test_no_output "python execfile ('${pyfile}')" ""
|
||||
|
||||
gdb_test "Test_Events" "Event testers registered."
|
||||
gdb_test_no_output "set non-stop on"
|
||||
gdb_test_no_output "set target-async on"
|
||||
|
||||
gdb_breakpoint "main"
|
||||
gdb_breakpoint "thread2"
|
||||
gdb_breakpoint "thread3"
|
||||
|
||||
send_gdb "run\n"
|
||||
gdb_expect {
|
||||
-re "event type: stop.*
|
||||
.*stop reason: breakpoint.*
|
||||
.*breakpoint number: 1.*
|
||||
.*thread num: 1.*" {
|
||||
pass "reached breakpoint 1"
|
||||
}
|
||||
timeout {
|
||||
fail "did not reach breakpoint 1"
|
||||
}
|
||||
}
|
||||
|
||||
send_gdb "next\n"
|
||||
gdb_expect {
|
||||
-re "event type: stop.*
|
||||
.*stop reason: breakpoint.*
|
||||
.*breakpoint number: 2.*
|
||||
.*thread num: 2.*" {
|
||||
pass "reached breakpoint 2"
|
||||
}
|
||||
timeout {
|
||||
fail "did not reach breakpoint 2"
|
||||
}
|
||||
}
|
||||
|
||||
send_gdb "next\n"
|
||||
gdb_expect {
|
||||
-re "event type: stop.*
|
||||
.*stop reason: breakpoint.*
|
||||
.*breakpoint number: 3.*
|
||||
.*thread num: 3.*" {
|
||||
pass "reached breakpoint 3"
|
||||
}
|
||||
timeout {
|
||||
fail "did not reach breakpoint 3"
|
||||
}
|
||||
}
|
||||
|
||||
send_gdb "continue&\n"
|
||||
gdb_expect {
|
||||
-re ".*event type: continue.*
|
||||
.*thread num: 1.*" {
|
||||
pass "continue thread 1"
|
||||
}
|
||||
timeout {
|
||||
fail "continue thread 1 failed"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test "thread 2" ".*Switching to thread 2.*"
|
||||
send_gdb "continue&\n"
|
||||
gdb_expect {
|
||||
-re ".*event type: continue.*
|
||||
.*thread num: 2.*" {
|
||||
pass "continue thread 2"
|
||||
}
|
||||
timeout {
|
||||
fail "continue thread 2 failed"
|
||||
}
|
||||
}
|
||||
|
||||
send_gdb "continue -a\n"
|
||||
gdb_expect {
|
||||
-re ".*stop reason: signal.*
|
||||
.*stop signal: SIGSEGV.*
|
||||
.*thread num: 3.*" {
|
||||
pass "thread 3 was signalled"
|
||||
}
|
||||
timeout {
|
||||
fail "thread 3 was not signalled"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user