From 2bce2763858358b753f1da7b2bb3da0215ed8bfc Mon Sep 17 00:00:00 2001 From: Kevin Pouget Date: Thu, 1 Sep 2011 11:08:23 +0200 Subject: [PATCH] New ObjFile event --- gdb/Makefile.in | 6 +++ gdb/NEWS | 2 + gdb/doc/gdb.texinfo | 15 ++++++-- gdb/python/py-event.h | 1 + gdb/python/py-events.h | 1 + gdb/python/py-evts.c | 3 ++ gdb/python/py-inferior.c | 25 +++++++++++++ gdb/python/py-newobjfileevent.c | 53 ++++++++++++++++++++++++++++ gdb/python/python-internal.h | 2 + gdb/python/python.c | 6 ++- gdb/testsuite/gdb.python/py-events-shlib.c | 20 ++++++++++ gdb/testsuite/gdb.python/py-events.c | 3 ++ gdb/testsuite/gdb.python/py-events.exp | 26 +++++++++++--- gdb/testsuite/gdb.python/py-events.py | 20 ++++++++++ 14 files changed, 172 insertions(+), 11 deletions(-) create mode 100644 gdb/python/py-newobjfileevent.c create mode 100644 gdb/testsuite/gdb.python/py-events-shlib.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 826d339..986588b 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -289,6 +289,7 @@ SUBDIR_PYTHON_OBS = \ py-inferior.o \ py-infthread.o \ py-lazy-string.o \ + py-newobjfileevent.o \ py-objfile.o \ py-param.o \ py-prettyprint.o \ @@ -319,6 +320,7 @@ SUBDIR_PYTHON_SRCS = \ python/py-inferior.c \ python/py-infthread.c \ python/py-lazy-string.c \ + python/py-newobjfileevent.c \ python/py-objfile.c \ python/py-param.c \ python/py-prettyprint.c \ @@ -2115,6 +2117,10 @@ py-lazy-string.o: $(srcdir)/python/py-lazy-string.c $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-lazy-string.c $(POSTCOMPILE) +py-newobjfileevent.o: $(srcdir)/python/py-newobjfileevent.c + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-newobjfileevent.c + $(POSTCOMPILE) + py-objfile.o: $(srcdir)/python/py-objfile.c $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-objfile.c $(POSTCOMPILE) diff --git a/gdb/NEWS b/gdb/NEWS index 255a22e..bb5795c 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -38,6 +38,8 @@ ** Symbols now provide the "type" attribute, the type of the symbol. + ** A new event "gdb.newobjfile" has been added. + * libthread-db-search-path now supports two special values: $sdir and $pdir. $sdir specifies the default system locations of shared libraries. $pdir specifies the directory where the libpthread used by the application diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 23b2a98..056776a 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -22327,6 +22327,13 @@ A reference to the breakpoint that was hit of type @code{gdb.Breakpoint}. @end defivar @end table +@item events.newobjfile +Emits @code{gdb.NewObjFileEvent} which indicates that a new object-file has +been loaded by @value{GDBN}. + +During the callback, ``current objfile'' will be set to the new object file +(@pxref{Objfiles In Python}). + @end table @node Threads In Python @@ -22949,10 +22956,10 @@ The following objfile-related functions are available in the @findex gdb.current_objfile @defun current_objfile -When auto-loading a Python script (@pxref{Auto-loading}), @value{GDBN} -sets the ``current objfile'' to the corresponding objfile. This -function returns the current objfile. If there is no current objfile, -this function returns @code{None}. +When auto-loading a Python script (@pxref{Auto-loading}) and during +new-object-file callbacks, @value{GDBN} sets the ``current objfile'' to +the corresponding objfile. This function returns the current objfile. +If there is no current objfile, this function returns @code{None}. @end defun @findex gdb.objfiles diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h index f4b3ee2..9069a51 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -111,6 +111,7 @@ extern int evpy_emit_event (PyObject *event, extern PyObject *create_event_object (PyTypeObject *py_type); extern PyObject *create_thread_event_object (PyTypeObject *py_type); +extern int emit_new_objfile_event (struct objfile *objfile); extern void evpy_dealloc (PyObject *self); extern int evpy_add_attribute (PyObject *event, diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h index bd54418..70f45a4 100644 --- a/gdb/python/py-events.h +++ b/gdb/python/py-events.h @@ -45,6 +45,7 @@ typedef struct eventregistry_object *stop; eventregistry_object *cont; eventregistry_object *exited; + eventregistry_object *newobjfile; PyObject *module; diff --git a/gdb/python/py-evts.c b/gdb/python/py-evts.c index 50c05f3..c8d1044 100644 --- a/gdb/python/py-evts.c +++ b/gdb/python/py-evts.c @@ -58,6 +58,9 @@ gdbpy_initialize_py_events (void) if (add_new_registry (&gdb_py_events.exited, "exited") < 0) goto fail; + if (add_new_registry (&gdb_py_events.newobjfile, "newobjfile") < 0) + goto fail; + Py_INCREF (gdb_py_events.module); if (PyModule_AddObject (gdb_module, "events", diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index 6add681..63ffc2b 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -22,6 +22,7 @@ #include "gdbcore.h" #include "gdbthread.h" #include "inferior.h" +#include "objfiles.h" #include "observer.h" #include "python-internal.h" #include "arch-utils.h" @@ -125,6 +126,29 @@ python_inferior_exit (struct inferior *inf) do_cleanups (cleanup); } +/* Callback used to notify Python listeners about new objfiles loaded in the + inferior. Python global variable 'gdb.current_objfile ()' will be set + during the notifications. */ + +static void +python_new_objfile (struct objfile *objfile) +{ + struct cleanup *cleanup; + + if (objfile == NULL) + return; + + cleanup = ensure_python_env (get_objfile_arch (objfile), current_language); + + gdbpy_current_objfile = objfile; + + if (emit_new_objfile_event (objfile) < 0) + gdbpy_print_stack (); + + do_cleanups (cleanup); + gdbpy_current_objfile = NULL; +} + /* Return a reference to the Python object of type Inferior representing INFERIOR. If the object has already been created, return it and increment the reference count, otherwise, create it. @@ -701,6 +725,7 @@ gdbpy_initialize_inferior (void) observer_attach_normal_stop (python_on_normal_stop); observer_attach_target_resumed (python_on_resume); observer_attach_inferior_exit (python_inferior_exit); + observer_attach_new_objfile (python_new_objfile); membuf_object_type.tp_new = PyType_GenericNew; if (PyType_Ready (&membuf_object_type) < 0) diff --git a/gdb/python/py-newobjfileevent.c b/gdb/python/py-newobjfileevent.c new file mode 100644 index 0000000..20e2b31 --- /dev/null +++ b/gdb/python/py-newobjfileevent.c @@ -0,0 +1,53 @@ +/* Python interface to new object file loading events. + + Copyright (C) 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 . */ + +#include "py-event.h" + +static PyTypeObject new_objfile_event_object_type; + +PyObject * +create_new_objfile_event_object (void) +{ + return create_event_object (&new_objfile_event_object_type); +} + +/* Callback function which notifies observers when a new objfile event occurs. + This function will create a new Python new_objfile event object. + Return -1 if emit fails. */ + +int +emit_new_objfile_event (struct objfile *objfile) +{ + PyObject *event; + + if (evregpy_no_listeners_p (gdb_py_events.newobjfile)) + return 0; + + event = create_new_objfile_event_object (); + if (event) + return evpy_emit_event (event, gdb_py_events.newobjfile); + return -1; +} + +GDBPY_NEW_EVENT_TYPE (new_objfile, + "gdb.NewObjFileEvent", + "NewObjFileEvent", + "GDB new object file event object", + event_object_type, + static); diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 996b23b..a64ded2 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -211,6 +211,7 @@ void gdbpy_initialize_breakpoint_event (void); 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); struct cleanup *make_cleanup_py_decref (PyObject *py); @@ -219,6 +220,7 @@ struct cleanup *ensure_python_env (struct gdbarch *gdbarch, extern struct gdbarch *python_gdbarch; extern const struct language_defn *python_language; +extern struct objfile *gdbpy_current_objfile; /* Use this after a TRY_EXCEPT to throw the appropriate Python exception. */ diff --git a/gdb/python/python.c b/gdb/python/python.c index 03edce9..812fc61 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -891,8 +891,9 @@ gdbpy_progspaces (PyObject *unused1, PyObject *unused2) /* The "current" objfile. This is set when gdb detects that a new objfile has been loaded. It is only set for the duration of a call to - source_python_script_for_objfile; it is NULL at other times. */ -static struct objfile *gdbpy_current_objfile; + source_python_script_for_objfile and new_objfile callbacks; it is NULL at + other times. */ +struct objfile *gdbpy_current_objfile; /* Set the current objfile to OBJFILE and then read STREAM,FILE as Python code. */ @@ -1209,6 +1210,7 @@ Enables or disables printing of Python stack traces."), gdbpy_initialize_continue_event (); gdbpy_initialize_exited_event (); gdbpy_initialize_thread_event (); + gdbpy_initialize_new_objfile_event () ; observer_attach_before_prompt (before_prompt_hook); diff --git a/gdb/testsuite/gdb.python/py-events-shlib.c b/gdb/testsuite/gdb.python/py-events-shlib.c new file mode 100644 index 0000000..2a17bbf --- /dev/null +++ b/gdb/testsuite/gdb.python/py-events-shlib.c @@ -0,0 +1,20 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 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 . */ + + +void do_nothing (void) {} + diff --git a/gdb/testsuite/gdb.python/py-events.c b/gdb/testsuite/gdb.python/py-events.c index ceb697e..5ac72f2 100644 --- a/gdb/testsuite/gdb.python/py-events.c +++ b/gdb/testsuite/gdb.python/py-events.c @@ -16,6 +16,8 @@ along with this program. If not, see . */ +extern void do_nothing (void); + int second(){ return 12; } @@ -25,5 +27,6 @@ int first(){ } int main (){ + do_nothing(); return first(); } diff --git a/gdb/testsuite/gdb.python/py-events.exp b/gdb/testsuite/gdb.python/py-events.exp index e5d6daf..11d7e00 100644 --- a/gdb/testsuite/gdb.python/py-events.exp +++ b/gdb/testsuite/gdb.python/py-events.exp @@ -24,23 +24,39 @@ if $tracelevel then { load_lib gdb-python.exp +set libfile "py-events-shlib" +set libsrc $srcdir/$subdir/$libfile.c +set lib_sl $objdir/$subdir/$libfile.so +set lib_opts debug + set testfile "py-events" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} +set exec_opts [list debug shlib=$lib_sl] set pyfile ${srcdir}/${subdir}/${testfile}.py -if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { +if [get_compiler_info ${binfile}] { return -1 } +if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != "" + || [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != ""} { + untested "Could not compile either $libsrc or $srcdir/$subdir/$srcfile." + return -1 +} + +# Start with a fresh gdb. +clean_restart ${testfile} + 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_Newobj_Events" "New ObjectFile Event tester registered." "Register new objfile event handler" + +gdb_breakpoint "main" {temporary} + +gdb_test "run" ".*event type: new_objfile.*new objfile name.*" "New objfile notification" gdb_test "Test_Events" "Event testers registered." diff --git a/gdb/testsuite/gdb.python/py-events.py b/gdb/testsuite/gdb.python/py-events.py index 9f05b9f..12e36e8 100644 --- a/gdb/testsuite/gdb.python/py-events.py +++ b/gdb/testsuite/gdb.python/py-events.py @@ -48,6 +48,14 @@ def continue_handler (event): if ( event.inferior_thread is not None) : print "thread num: %s" % (event.inferior_thread.num); +def new_objfile_handler (event): + if (isinstance (event, gdb.NewObjFileEvent)): + print "event type: new_objfile" + if (gdb.current_objfile () is not None): + print "new objfile name: %s" % (gdb.current_objfile ().filename) + else: + print "new objfile is None" + class test_events (gdb.Command): """Test events.""" @@ -62,3 +70,15 @@ class test_events (gdb.Command): print "Event testers registered." test_events () + +class test_newobj_events (gdb.Command): + """NewObj events.""" + + def __init__ (self): + gdb.Command.__init__ (self, "test_newobj_events", gdb.COMMAND_STACK) + + def invoke (self, arg, from_tty): + gdb.events.newobjfile.connect (new_objfile_handler) + print "New ObjectFile Event tester registered." + +test_newobj_events () -- 1.7.6