From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26888 invoked by alias); 23 Aug 2009 15:34:54 -0000 Mailing-List: contact archer-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: List-Id: Received: (qmail 26877 invoked by uid 22791); 23 Aug 2009 15:34:52 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org MIME-Version: 1.0 Date: Sun, 23 Aug 2009 15:34:00 -0000 Message-ID: <36a35d480908230834n73393daduc92857e82aa2f234@mail.gmail.com> Subject: [RFC][1/5] Changes to the current branch From: Oguz Kayral To: archer@sourceware.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-SW-Source: 2009-q3/txt/msg00149.txt.bz2 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 registri= es. * 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 =3D \ 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 =3D \ python/python.c \ python/python-block.c \ @@ -304,7 +311,14 @@ SUBDIR_PYTHON_SRCS =3D \ 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 =3D SUBDIR_PYTHON_LDFLAGS=3D SUBDIR_PYTHON_CFLAGS=3D @@ -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 =3D 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) >=3D 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 =3D 0; + breakpoint_object *breakpoint =3D NULL; + + if (bppy_live =3D=3D 0) + return NULL; + + for (i =3D 0; out < bppy_live; i++) + { + if (! bppy_breakpoints[i]) + continue; + + if (bs->breakpoint_at =3D=3D bppy_breakpoints[i]->bp->loc) + breakpoint =3D bppy_breakpoints[i]; + + ++out; + } + + return breakpoint; +} + =0C /* 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 igno= re) 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 =3D (char *) target_signal_to_name (inferior_thread()->stop_signal); + + state =3D PyGILState_Ensure (); + + emit_stop_event (bs, stop_signal); + + PyGILState_Release (state); +} + +static void +python_on_resume (ptid_t ptid) +{ + PyGILState_STATE state; + + state =3D 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 =3D (inferior_object *) find_inferior_object (PIDGET(tp->ptid)); + if (!inf_obj) + return; + + /* Find thread entry in its inferior's thread_list. */ + for (entry =3D &inf_obj->threads; *entry !=3D NULL; entry =3D &(*entry)-= >next) + if ((*entry)->thread_obj->thread =3D=3D tp) + break; + + if (!*entry) + return; + + thread_obj =3D (*entry)->thread_obj; + + state =3D PyGILState_Ensure (); + + if (get_internalvar_integer (lookup_internalvar ("_exitcode"), &exitcode_val)) + exit_code =3D &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 =3D 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 =3D find_inferior_object (PIDGET (tp->ptid)); Py_INCREF (thread_obj->inf_obj); + thread_obj->stop_eventregistry =3D create_eventregistry_object (); + thread_obj->breakpoint_stop_eventregistry =3D create_eventregistry_objec= t (); + thread_obj->signal_stop_eventregistry =3D create_eventregistry_object (); + thread_obj->continue_eventregistry =3D create_eventregistry_object (); + thread_obj->exited_eventregistry =3D 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 =3D (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 =3D (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 =3D (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 =3D (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 =3D (thread_object *) self; + + THPY_REQUIRE_VALID (thread_obj); + + Py_INCREF (thread_obj->exited_eventregistry); + + return (PyObject *) (thread_obj->exited_eventregistry); +} =0C /* Implementation of Inferior.frames () -> (gdb.Frame, ...). @@ -194,7 +264,7 @@ PyObject * gdbpy_selected_thread (PyObject *self, PyObject *args) { PyObject *thread_obj; - + thread_obj =3D (PyObject *) find_thread_object (inferior_ptid); if (thread_obj) { @@ -223,6 +293,11 @@ gdbpy_initialize_thread (void) static PyGetSetDef thread_object_getset[] =3D { { "num", thpy_get_num, NULL, "ID of the thread, as assigned by GDB.", NU= LL }, + { "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 =3D []");