diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 5bab360..1de1666 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -290,6 +290,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 \ @@ -320,6 +321,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 \ @@ -2082,6 +2084,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) @@ -2130,6 +2136,7 @@ py-value.o: $(srcdir)/python/py-value.c $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-value.c $(POSTCOMPILE) + # # Dependency tracking. Most of this is conditional on GNU Make being # found by configure; if GNU Make is not found, we fall back to a diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 584a520..1512ea3 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -22147,6 +22147,12 @@ 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: +@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. + @table @code @defivar SignalEvent stop_signal A string representing the signal received by the inferior. A list of possible @@ -22789,10 +22795,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 bc95521..9a3ba82 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -105,6 +105,7 @@ typedef struct extern int emit_continue_event (ptid_t ptid); extern int emit_exited_event (LONGEST exit_code); +extern int emit_new_objfile_event (struct objfile *objfile); extern int evpy_emit_event (PyObject *event, eventregistry_object *registry); diff --git a/gdb/python/py-events.h b/gdb/python/py-events.h index 6d4dae5..9c42e39 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 45f5f04..0d1d3ce 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" @@ -129,6 +130,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 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. */ @@ -669,6 +693,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); if (PyType_Ready (&membuf_object_type) < 0) return; 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 d3cb788..cc9108f 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -207,6 +207,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); @@ -215,6 +216,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 8a7bc66..c96984c 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -811,8 +811,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. */ @@ -1074,6 +1075,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 () ; PyRun_SimpleString ("import gdb"); PyRun_SimpleString ("gdb.pretty_printers = []"); 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..1cf7cc7 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 ()