This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/3] Add a gdb.events.frame_change event registry


---
 ChangeLog                              |  7 ++++
 gdb/Makefile.in                        |  6 +++
 gdb/NEWS                               |  5 +++
 gdb/doc/gdb.texinfo                    |  9 +++++
 gdb/python/py-events.h                 |  1 +
 gdb/python/py-evts.c                   |  3 ++
 gdb/python/py-framechangeevent.c       | 73 ++++++++++++++++++++++++++++++++++
 gdb/python/py-framechangeevent.h       | 29 ++++++++++++++
 gdb/python/python-internal.h           |  1 +
 gdb/python/python.c                    | 18 +++++++++
 gdb/testsuite/gdb.python/py-events.exp |  8 ++++
 gdb/testsuite/gdb.python/py-events.py  |  8 ++++
 12 files changed, 168 insertions(+)
 create mode 100644 gdb/python/py-framechangeevent.c
 create mode 100644 gdb/python/py-framechangeevent.h

diff --git a/ChangeLog b/ChangeLog
index 0ee72e5..4f278fa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,13 @@
 	* varobj.c: Idem.
 	* doc/observer.texi: add a frame_changed observer
 	* frame.c: Idem
+	* py-framechangeevent.c: add python frame_change event registry.
+	* py-framechangeevent.h: Idem.
+	* python/python.c (python_frame_changed): Idem.
+	* doc/gdb.texinfo: Idem.
+	* Makefile.in: Idem.
+	* testsuite/gdb.python/py-events.exp: Idem.
+	* testsuite/gdb.python/py-events.py: Idem.
 
 2013-04-29  Jan-Benedict Glaw  <jbglaw@lug-owl.de>
 
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index c891c83..748d0ca 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -288,6 +288,7 @@ SUBDIR_PYTHON_OBS = \
 	py-exitedevent.o \
 	py-finishbreakpoint.o \
 	py-frame.o \
+	py-framechangeevent.o \
 	py-function.o \
 	py-gdb-readline.o \
 	py-inferior.o \
@@ -322,6 +323,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-exitedevent.c \
 	python/py-finishbreakpoint.c \
 	python/py-frame.c \
+	python/py-framechangeevent.c \
 	python/py-function.c \
 	python/py-gdb-readline.c \
 	python/py-inferior.c \
@@ -2141,6 +2143,10 @@ py-frame.o: $(srcdir)/python/py-frame.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-frame.c
 	$(POSTCOMPILE)
 
+py-framechangeevent.o: $(srcdir)/python/py-framechangeevent.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-framechangeevent.c
+	$(POSTCOMPILE)
+
 py-function.o: $(srcdir)/python/py-function.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-function.c
 	$(POSTCOMPILE)
diff --git a/gdb/NEWS b/gdb/NEWS
index 76b48e8..af36e1f 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -51,6 +51,11 @@ show remote trace-status-packet
   ** The -trace-save MI command can optionally save trace buffer in Common
      Trace Format now.
 
+* Python scripting
+
+  ** User visible frame change events are notified through
+     the gdb.events.frame_change event registry
+
 *** Changes in GDB 7.6
 
 * Target record has been renamed to record-full.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 8bc1213..df3de08 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -24588,6 +24588,15 @@ A reference to the object file (@code{gdb.Objfile}) which has been loaded.
 @xref{Objfiles In Python}, for details of the @code{gdb.Objfile} object.
 @end defvar
 
+@item events.frame_change
+Emits @code{gdb.FrameChangeEvent} which indicates that the selected frame
+has changed in a user visible way (such by hitting a breakpoint, or moving
+in the callstack due to a user command).
+
+@defvar FrameChangeEvent.frame
+A reference to the newly selected frame (@code{gdb.Frame})
+@end defvar
+
 @end table
 
 @node Threads In Python
diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h
index 537bcc9..a61858c 100644
--- a/gdb/python/py-events.h
+++ b/gdb/python/py-events.h
@@ -45,6 +45,7 @@ typedef struct
   eventregistry_object *cont;
   eventregistry_object *exited;
   eventregistry_object *new_objfile;
+  eventregistry_object *frame_change;
 
   PyObject *module;
 
diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c
index 4c079e2..f4d1fbf 100644
--- a/gdb/python/py-evts.c
+++ b/gdb/python/py-evts.c
@@ -81,6 +81,9 @@ gdbpy_initialize_py_events (void)
   if (add_new_registry (&gdb_py_events.new_objfile, "new_objfile") < 0)
     goto fail;
 
+  if (add_new_registry (&gdb_py_events.frame_change, "frame_change") < 0)
+    goto fail;
+
 #ifndef IS_PY3K
   Py_INCREF (gdb_py_events.module);
 #endif
diff --git a/gdb/python/py-framechangeevent.c b/gdb/python/py-framechangeevent.c
new file mode 100644
index 0000000..7b4bec9
--- /dev/null
+++ b/gdb/python/py-framechangeevent.c
@@ -0,0 +1,73 @@
+/* Python interface to inferior frame events.
+
+   Copyright (C) 2009-2013 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 "py-framechangeevent.h"
+
+static PyTypeObject frame_change_event_object_type;
+
+static PyObject *
+create_frame_change_event_object (struct frame_info *frame)
+{
+  PyObject *frame_change_event;
+  PyObject *py_frame;
+
+  frame_change_event = create_event_object (&frame_change_event_object_type);
+  if (!frame_change_event)
+    goto fail;
+
+  py_frame = frame != NULL ? frame_info_to_frame_object (frame) : Py_None;
+  if (!py_frame || evpy_add_attribute (frame_change_event,
+                                       "frame", py_frame) < 0)
+    goto fail_frame;
+
+  Py_XDECREF (py_frame);
+  return frame_change_event;
+
+ fail_frame:
+  Py_XDECREF (py_frame);
+ fail:
+  Py_XDECREF (frame_change_event);
+  return NULL;
+}
+
+/* Callback observers when a frame event occurs.  This function will create a
+   new Python frame event object. return 0 if the event was created and
+   emitted successfully otherwise returns -1.  */
+
+int
+emit_frame_change_event (struct frame_info *frame)
+{
+  PyObject *frame_change_event_obj = NULL;
+
+  if (evregpy_no_listeners_p (gdb_py_events.frame_change))
+    return 0;
+
+  frame_change_event_obj = create_frame_change_event_object (frame);
+  if (frame_change_event_obj)
+    return evpy_emit_event (frame_change_event_obj, gdb_py_events.frame_change);
+  return -1;
+}
+
+GDBPY_NEW_EVENT_TYPE (frame_change,
+                      "gdb.FrameChangeEvent",
+                      "FrameChangeEvent",
+                      "GDB frame event object",
+                      event_object_type,
+                      static);
diff --git a/gdb/python/py-framechangeevent.h b/gdb/python/py-framechangeevent.h
new file mode 100644
index 0000000..e7564b0
--- /dev/null
+++ b/gdb/python/py-framechangeevent.h
@@ -0,0 +1,29 @@
+/* Python interface to inferior events.
+
+   Copyright (C) 2009-2013 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_FRAMECHANGEEVENT_H
+#define GDB_PY_FRAMECHANGEEVENT_H
+
+#include "py-event.h"
+
+extern void frame_change_evpy_dealloc (PyObject *self);
+
+extern int emit_frame_change_event (struct frame_info* frame);
+
+#endif /* GDB_PY_FRAMECHANGEEVENT_H */
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index ea97226..676096d 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -301,6 +301,7 @@ void gdbpy_initialize_continue_event (void);
 void gdbpy_initialize_exited_event (void);
 void gdbpy_initialize_thread_event (void);
 void gdbpy_initialize_new_objfile_event (void);
+void gdbpy_initialize_frame_change_event (void);
 void gdbpy_initialize_arch (void);
 
 struct cleanup *make_cleanup_py_decref (PyObject *py);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 67d06e5..ab578ed 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -72,6 +72,7 @@ static const char *gdbpy_should_print_stack = python_excp_message;
 #include "observer.h"
 #include "interps.h"
 #include "event-top.h"
+#include "py-framechangeevent.h"
 
 static PyMethodDef GdbMethods[];
 
@@ -881,6 +882,21 @@ gdbpy_initialize_events (void)
     }
 }
 
+/* Callback for frame changed observer */
+static void
+python_frame_changed (struct frame_info *frame)
+{
+  struct cleanup *cleanup;
+  struct gdbarch *arch = frame ? get_frame_arch(frame) : target_gdbarch();
+
+  cleanup = ensure_python_env (arch, current_language);
+
+  if (emit_frame_change_event (frame) < 0)
+    gdbpy_print_stack ();
+
+  do_cleanups (cleanup);
+}
+
 
 
 static void
@@ -1630,9 +1646,11 @@ message == an error message without a stack will be printed."),
   gdbpy_initialize_exited_event ();
   gdbpy_initialize_thread_event ();
   gdbpy_initialize_new_objfile_event () ;
+  gdbpy_initialize_frame_change_event () ;
   gdbpy_initialize_arch ();
 
   observer_attach_before_prompt (before_prompt_hook);
+  observer_attach_frame_changed (python_frame_changed);
 
   gdbpy_to_string_cst = PyString_FromString ("to_string");
   gdbpy_children_cst = PyString_FromString ("children");
diff --git a/gdb/testsuite/gdb.python/py-events.exp b/gdb/testsuite/gdb.python/py-events.exp
index 7bd6562..dd3fd75 100644
--- a/gdb/testsuite/gdb.python/py-events.exp
+++ b/gdb/testsuite/gdb.python/py-events.exp
@@ -77,6 +77,14 @@ gdb_test "step 3" ".*event type: continue.*
 .*breakpoint number: 4.*
 all threads stopped"
 
+# Test that up triggers frame change event
+gdb_test "up" ".*event type: frame change.*
+.*frame name: first.*"
+
+# Test that breakpoint triggers frame change event
+gdb_test "continue" ".*event type: frame change.*
+.*frame name: do_nothing.*"
+
 delete_breakpoints
 
 #test exited event.
diff --git a/gdb/testsuite/gdb.python/py-events.py b/gdb/testsuite/gdb.python/py-events.py
index bfab78e..b7244b2 100644
--- a/gdb/testsuite/gdb.python/py-events.py
+++ b/gdb/testsuite/gdb.python/py-events.py
@@ -60,6 +60,13 @@ def new_objfile_handler (event):
     else:
         print ("new objfile is None")
 
+def frame_change_handler (event):
+    if (isinstance (event, gdb.FrameChangeEvent)):
+        print ("event type: frame change")
+        name = event.frame.name()
+        if (name is not None):
+            print ("frame name: %s" % (name))
+
 class test_events (gdb.Command):
     """Test events."""
 
@@ -71,6 +78,7 @@ class test_events (gdb.Command):
         gdb.events.stop.connect (breakpoint_stop_handler)
         gdb.events.exited.connect (exit_handler)
         gdb.events.cont.connect (continue_handler)
+        gdb.events.frame_change.connect (frame_change_handler)
         print ("Event testers registered.")
 
 test_events ()
-- 
1.8.2.1



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]