+2011-02-04 Sami Wagiaalla <swagiaal@redhat.com>
+ Oguz Kayral <oguzkayral@gmail.com>
+
+ * python/py-inferior.c (python_on_normal_stop): New function.
+ (python_on_resume): New function.
+ (python_inferior_exit): New function.
+ (gdbpy_initialize_inferior): Add normal_stop, target_resumed, and
+ inferior_exit observers.
+ * python/py-evtregistry.c: New file.
+ * python/py-threadevent.c : New file.
+ * python/py-event.c: New file.
+ * python/py-evts.c: New file.
+ * python/py-continueevent.c: New file.
+ * python/py-bpevent.c: New file.
+ * python/py-signalevent.c: New file.
+ * python/py-exetiedevent.c: New file.
+ * python/py-breakpoint.c (gdbpy_breakpoint_from_bpstats): New function.
+ Move struct breakpoint_object from here...
+ * python/python-internal.h: ... to here.
+ * python/py-event.h: New file.
+ * python/py-events.h: New file.
+ * Makefile.in (SUBDIR_PYTHON_OBS): Add py-breakpointstopevent.o,
+ py-continueevent.o, py-event.o, py-eventregistry.o, py-events.o,
+ py-exitedevent.o, py-signalstopevent.o, and py-stopevent.o.
+ (SUBDIR_PYTHON_SRCS): Add py-breakpointstopevent.c,
+ py-continueevent.c, py-event.c, py-eventregistry.c, py-events.c,
+ py-exitedevent.c, py-signalstopevent.c, and py-stopevent.c.
+ Add build rules for all the above.
+
2011-02-04 Tom Tromey <tromey@redhat.com>
* dwarf2read.c (dwarf2_section_empty_p): New function.
python.o \
py-auto-load.o \
py-block.o \
+ py-bpevent.o \
py-breakpoint.o \
py-cmd.o \
+ py-continueevent.o \
+ py-event.o \
+ py-evtregistry.o \
+ py-evts.o \
+ py-exitedevent.o \
py-frame.o \
py-function.o \
py-inferior.o \
py-param.o \
py-prettyprint.o \
py-progspace.o \
+ py-signalevent.o \
+ py-stopevent.o \
py-symbol.o \
py-symtab.o \
+ py-threadevent.o \
py-type.o \
py-utils.o \
py-value.o
+
SUBDIR_PYTHON_SRCS = \
python/python.c \
python/py-auto-load.c \
python/py-block.c \
+ python/py-bpevent.c \
python/py-breakpoint.c \
python/py-cmd.c \
+ python/py-continueevent.c \
+ python/py-event.c \
+ python/py-evtregistry.c \
+ python/py-evts.c \
+ python/py-exitedevent.c \
python/py-frame.c \
python/py-function.c \
python/py-inferior.c \
python/py-param.c \
python/py-prettyprint.c \
python/py-progspace.c \
+ python/py-signalevent.c \
+ python/py-stopevent.c \
python/py-symbol.c \
python/py-symtab.c \
+ python/py-threadevent.c \
python/py-type.c \
python/py-utils.c \
python/py-value.c
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-block.c
$(POSTCOMPILE)
+py-bpevent.o: $(srcdir)/python/py-bpevent.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-bpevent.c
+ $(POSTCOMPILE)
+
py-breakpoint.o: $(srcdir)/python/py-breakpoint.c
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-breakpoint.c
$(POSTCOMPILE)
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-cmd.c
$(POSTCOMPILE)
+py-continueevent.o: $(srcdir)/python/py-continueevent.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-continueevent.c
+ $(POSTCOMPILE)
+
+py-event.o: $(srcdir)/python/py-event.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-event.c
+ $(POSTCOMPILE)
+
+py-evtregistry.o: $(srcdir)/python/py-evtregistry.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-evtregistry.c
+ $(POSTCOMPILE)
+
+py-evts.o: $(srcdir)/python/py-evts.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-evts.c
+ $(POSTCOMPILE)
+
+py-exitedevent.o: $(srcdir)/python/py-exitedevent.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-exitedevent.c
+ $(POSTCOMPILE)
+
py-frame.o: $(srcdir)/python/py-frame.c
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-frame.c
$(POSTCOMPILE)
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-progspace.c
$(POSTCOMPILE)
+py-signalevent.o: $(srcdir)/python/py-signalevent.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-signalevent.c
+ $(POSTCOMPILE)
+
+py-stopevent.o: $(srcdir)/python/py-stopevent.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-stopevent.c
+ $(POSTCOMPILE)
+
py-symbol.o: $(srcdir)/python/py-symbol.c
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symbol.c
$(POSTCOMPILE)
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symtab.c
$(POSTCOMPILE)
+py-threadevent.o: $(srcdir)/python/py-threadevent.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-threadevent.c
+ $(POSTCOMPILE)
+
py-type.o: $(srcdir)/python/py-type.c
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-type.c
$(POSTCOMPILE)
** The gdb.InferiorThread class has a new "name" attribute. This
holds the thread's name.
+ ** 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
* Selecting Pretty-Printers:: How GDB chooses a pretty-printer.
* Writing a Pretty-Printer:: Writing a Pretty-Printer.
* Inferiors In Python:: Python representation of inferiors (processes)
+* Events In Python:: Listening for events from @value{GDBN}.
* Threads In Python:: Accessing inferior threads from Python.
* Commands In Python:: Implementing new commands in Python.
* Parameters In Python:: Adding new @value{GDBN} parameters.
@node Inferiors In Python
@subsubsection Inferiors In Python
-@cindex inferiors in python
+@cindex inferiors in Python
@findex gdb.Inferior
Programs which are being run under @value{GDBN} are called inferiors
@end defmethod
@end table
+@node Events In Python
+@subsubsection Events In Python
+@cindex inferior events in Python
+
+@value{GDBN} provides a general event facility so that Python code can be
+notified of various state changes, particularly changes that occur in
+the inferior.
+
+An @dfn{event} is just an object that describes some state change. The
+type of the object and its attributes will vary depending on the details
+of the change. All the existing events are described below.
+
+In order to be notified of an event, you must register an event handler
+with an @dfn{event registry}. An event registry is an object in the
+@code{gdb.events} module which dispatches particular events. A registry
+provides methods to register and unregister event handlers:
+
+@table @code
+@defmethod EventRegistry connect object
+Add the given callable @var{object} to the registry. This object will be
+called when an event corresponding to this registry occurs.
+@end defmethod
+
+@defmethod EventRegistry disconnect object
+Remove the given @var{object} from the registry. Once removed, the object
+will no longer receive notifications of events.
+@end defmethod
+@end table
+
+Here is an example:
+
+@smallexample
+def exit_handler (event):
+ print "event type: exit"
+ print "exit code: %d" % (event.exit_code)
+
+gdb.events.exited.connect (exit_handler)
+@end smallexample
+
+In the above example we connect our handler @code{exit_handler} to the
+registry @code{events.exited}. Once connected, @code{exit_handler} gets
+called when the inferior exits. The argument @dfn{event} in this example is
+of type @code{gdb.ExitedEvent}. As you can see in the example the
+@code{ExitedEvent} object has an attribute which indicates the exit code of
+the inferior.
+
+The following is a listing of the event registries that are available and
+details of the events they emit:
+
+@table @code
+
+@item events.cont
+Emits @code{gdb.ThreadEvent}.
+
+Some events can be thread specific when @value{GDBN} is running in non-stop
+mode. When represented in Python, these events all extend
+@code{gdb.ThreadEvent}. Note, this event is not emitted directly; instead,
+events which are emitted by this or other modules might extend this event.
+Examples of these events are @code{gdb.BreakpointEvent} and
+@code{gdb.ContinueEvent}.
+
+@table @code
+@defivar ThreadEvent inferior_thread
+In non-stop mode this attribute will be set to the specific thread which was
+involved in the emitted event. Otherwise, it will be set to @code{None}.
+@end defivar
+@end table
+
+Emits @code{gdb.ContinueEvent} which extends @code{gdb.ThreadEvent}.
+
+This event indicates that the inferior has been continued after a stop. For
+inherited attribute refer to @code{gdb.ThreadEvent} above.
+
+@item events.exited
+Emits @code{events.ExitedEvent} which indicates that the inferior has exited.
+@code{events.ExitedEvent} has one attribute:
+@table @code
+@defivar ExitedEvent exit_code
+An integer representing the exit code which the inferior has returned.
+@end defivar
+@end table
+
+@item events.stop
+Emits @code{gdb.StopEvent} which extends @code{gdb.ThreadEvent}.
+
+Indicates that the inferior has stopped. All events emitted by this registry
+extend StopEvent. As a child of @code{gdb.ThreadEvent}, @code{gdb.StopEvent}
+will indicate the stopped thread when @value{GDBN} is running in non-stop
+mode. Refer to @code{gdb.ThreadEvent} above for more details.
+
+Emits @code{gdb.SignalEvent} which extends @code{gdb.StopEvent}.
+
+This event indicates that the inferior or one of its threads has received as
+signal. @code{gdb.SignalEvent} has the following attributes:
+
+@table @code
+@defivar SignalEvent stop_signal
+A string representing the signal received by the inferior. A list of possible
+signal values can be obtained by running the command @code{info signals} in
+the @value{GDBN} command prompt.
+@end defivar
+@end table
+
+Also emits @code{gdb.BreakpointEvent} which extends @code{gdb.StopEvent}.
+
+@code{gdb.BreakpointEvent} event indicates that a breakpoint has been hit, and
+has the following attributes:
+
+@table @code
+@defivar BreakpointEvent breakpoint
+A reference to the breakpoint that was hit of type @code{gdb.Breakpoint}.
+@xref{Breakpoints In Python}, for details of the @code{gdb.Breakpoint} object.
+@end defivar
+@end table
+
+@end table
+
@node Threads In Python
@subsubsection Threads In Python
@cindex threads in python
#include "cli/cli-script.h"
#include "ada-lang.h"
-/* From breakpoint.c. */
-typedef struct breakpoint_object breakpoint_object;
-
static PyTypeObject breakpoint_object_type;
/* Number of live breakpoints. */
#include "python-internal.h"
#include "arch-utils.h"
#include "language.h"
+#include "gdb_signals.h"
+#include "py-event.h"
+#include "py-stopevent.h"
struct threadlist_entry {
thread_object *thread_obj;
} \
} while (0)
+static void
+python_on_normal_stop (struct bpstats *bs, int print_frame)
+{
+ struct cleanup *cleanup;
+ enum target_signal stop_signal;
+
+ if (!find_thread_ptid (inferior_ptid))
+ return;
+
+ stop_signal = inferior_thread ()->suspend.stop_signal;
+
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ if (emit_stop_event (bs, stop_signal) < 0)
+ gdbpy_print_stack ();
+
+ do_cleanups (cleanup);
+}
+
+static void
+python_on_resume (ptid_t ptid)
+{
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ if (emit_continue_event (ptid) < 0)
+ gdbpy_print_stack ();
+
+ do_cleanups (cleanup);
+}
+
+static void
+python_inferior_exit (struct inferior *inf)
+{
+ struct cleanup *cleanup;
+ LONGEST exit_code = -1;
+ ptid_t ptidp;
+ struct target_waitstatus status;
+
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ get_last_target_status (&ptidp, &status);
+
+ exit_code = status.value.integer;
+
+ if (exit_code >= 0
+ && emit_exited_event (exit_code) < 0)
+ gdbpy_print_stack ();
+
+ do_cleanups (cleanup);
+}
+
/* Return a borrowed reference to the Python object of type Inferior
representing INFERIOR. If the object has already been created,
return it, otherwise, create it. Return NULL on failure. */
/* Finds the Python Inferior object for the given PID. Returns a
borrowed reference, or NULL if PID does not match any inferior
- obect.
- */
+ object. */
+
PyObject *
find_inferior_object (int pid)
{
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_inferior_exit (python_inferior_exit);
if (PyType_Ready (&membuf_object_type) < 0)
return;
/* Also needed to parse enum var_types. */
#include "command.h"
+#include "breakpoint.h"
#include "exceptions.h"
struct value;
struct language_defn;
struct program_space;
+struct bpstats;
extern PyObject *gdb_module;
extern PyTypeObject value_object_type;
extern PyTypeObject block_object_type;
extern PyTypeObject symbol_object_type;
+extern PyTypeObject event_object_type;
+extern PyTypeObject events_object_type;
+extern PyTypeObject stop_event_object_type;
+
+/* Defined in py-breakpoint.c */
+typedef struct breakpoint_object breakpoint_object;
typedef struct
{
thread_object *create_thread_object (struct thread_info *tp);
thread_object *find_thread_object (ptid_t ptid);
PyObject *find_inferior_object (int pid);
+PyObject *inferior_to_inferior_object (struct inferior *inferior);
struct block *block_object_to_block (PyObject *obj);
struct symbol *symbol_object_to_symbol (PyObject *obj);
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_py_events (void);
+void gdbpy_initialize_stop_event (void);
+void gdbpy_initialize_signal_event (void);
+void gdbpy_initialize_breakpoint_event (void);
+void gdbpy_initialize_continue_event (void);
+void gdbpy_initialize_exited_event (void);
+void gdbpy_initialize_thread_event (void);
struct cleanup *make_cleanup_py_decref (PyObject *py);
gdbpy_initialize_inferior ();
gdbpy_initialize_events ();
+ gdbpy_initialize_eventregistry ();
+ gdbpy_initialize_py_events ();
+ gdbpy_initialize_event ();
+ gdbpy_initialize_stop_event ();
+ gdbpy_initialize_signal_event ();
+ gdbpy_initialize_breakpoint_event ();
+ gdbpy_initialize_continue_event ();
+ gdbpy_initialize_exited_event ();
+ gdbpy_initialize_thread_event ();
+
PyRun_SimpleString ("import gdb");
PyRun_SimpleString ("gdb.pretty_printers = []");
+2011-02-04 Sami Wagiaalla <swagiaal@redhat.com>
+
+ * gdb.python/py-evthreads.c: New file.
+ * gdb.python/py-evthreads.exp: New file.
+ * gdb.python/py-events.py: New file.
+ * gdb.python/py-events.exp: New file.
+ * gdb.python/py-events.c: New file.
+
2011-02-04 David Daney <ddaney@caviumnetworks.com>
* gdb.base/catch-syscall.exp: Enable for mips*-linux*.