[RFC - Python] New ObjFile event

Kevin Pouget
2011-03-28T08:06:58Z

[-- Attachment #1: Type: text/plain, Size: 1393 bytes --]

Hello,

following this discussion at
http://sourceware.org/ml/gdb/2011-03/msg00136.html, I would like to
suggest a patch for the Python event system. Based on the ''exited",
"cont", ... events, this patch allows a python script to register an
interest to the loading of new object files in the debuggee. GDB
observer "observer_attach_new_objfile" is used to trigger the Python
callback.

This patch completes the auto-loading feature
(http://sourceware.org/gdb/current/onlinedocs/gdb/objfile_002dgdb_002epy-file.html#objfile_002dgdb_002epy-file),
and, likewise, allows Python's "gdb.current_objfile ()" to return the current
object file.

Here is an example of it utilization:

> def obj_handler (event):
>       if gdb.current_objfile () is not None:
>               print "-->",gdb.current_objfile ().filename
>       else:
>               print "---------------->Cleanup"
>
> gdb.events.newobjfile.connect (obj_handler)

There is still one thing I'm not happy with in the code, it's how to
'properly' access "gdbpy_current_objfile" ? I commented out "static"
and declared it "extern" when I needed it, but that's certainly not
the best way:

gdb/python/python.c
/*static*/ struct objfile *gdbpy_current_objfile;
gdb/python/py-inferior.c
extern struct objfile *gdbpy_current_objfile;

please let me know what you thing about it

Cordially,

Kevin

[-- Attachment #2: gdb-newobjfile.diff --]
[-- Type: application/octet-stream, Size: 6065 bytes --]

? gdb/python/py-newobjfileevent.c
Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1163
diff -u -r1.1163 Makefile.in
--- gdb/Makefile.in 9 Mar 2011 06:10:37 -0000 1.1163
+++ gdb/Makefile.in 28 Mar 2011 07:43:36 -0000
@@ -296,7 +296,8 @@
py-threadevent.o \
py-type.o \
py-utils.o \
- py-value.o
+ py-value.o \
+ py-newobjfileevent.o

SUBDIR_PYTHON_SRCS = \
python/python.c \
@@ -326,7 +327,8 @@
python/py-threadevent.c \
python/py-type.c \
python/py-utils.c \
- python/py-value.c
+ python/py-value.c \
+ python/py-newobjfileevent.c
SUBDIR_PYTHON_DEPS =
SUBDIR_PYTHON_LDFLAGS=
SUBDIR_PYTHON_CFLAGS=
@@ -2110,6 +2112,11 @@
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-value.c
$(POSTCOMPILE)

+py-newobjfileevent.o: $(srcdir)/python/py-newobjfileevent.c
+ $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-newobjfileevent.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
Index: gdb/python/py-event.h
===================================================================
RCS file: /cvs/src/src/gdb/python/py-event.h,v
retrieving revision 1.1
diff -u -r1.1 py-event.h
--- gdb/python/py-event.h 5 Feb 2011 05:27:23 -0000 1.1
+++ gdb/python/py-event.h 28 Mar 2011 07:43:36 -0000
@@ -105,6 +105,7 @@

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);
Index: gdb/python/py-events.h
===================================================================
RCS file: /cvs/src/src/gdb/python/py-events.h,v
retrieving revision 1.1
diff -u -r1.1 py-events.h
--- gdb/python/py-events.h 5 Feb 2011 05:27:23 -0000 1.1
+++ gdb/python/py-events.h 28 Mar 2011 07:43:36 -0000
@@ -45,6 +45,7 @@
eventregistry_object *stop;
eventregistry_object *cont;
eventregistry_object *exited;
+ eventregistry_object *newobjfile;

PyObject *module;

Index: gdb/python/py-evts.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-evts.c,v
retrieving revision 1.2
diff -u -r1.2 py-evts.c
--- gdb/python/py-evts.c 14 Mar 2011 15:43:51 -0000 1.2
+++ gdb/python/py-evts.c 28 Mar 2011 07:43:36 -0000
@@ -57,6 +57,9 @@

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,
Index: gdb/python/py-inferior.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-inferior.c,v
retrieving revision 1.7
diff -u -r1.7 py-inferior.c
--- gdb/python/py-inferior.c 17 Mar 2011 09:36:16 -0000 1.7
+++ gdb/python/py-inferior.c 28 Mar 2011 07:43:36 -0000
@@ -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,27 @@
do_cleanups (cleanup);
}

+extern struct objfile *gdbpy_current_objfile;
+static void
+python_new_objfile (struct objfile *objfile)
+{
+ struct cleanup *cleanup;
+
+ /* Will be NULL when clearing the symtab. */
+ if (objfile)
+ cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
+ else
+ cleanup = ensure_python_env (get_current_arch (), 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,7 +691,8 @@
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;

Index: gdb/python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.44
diff -u -r1.44 python-internal.h
--- gdb/python/python-internal.h 28 Feb 2011 19:38:34 -0000 1.44
+++ gdb/python/python-internal.h 28 Mar 2011 07:43:36 -0000
@@ -207,6 +207,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);

struct cleanup *make_cleanup_py_decref (PyObject *py);

Index: gdb/python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.63
diff -u -r1.63 python.c
--- gdb/python/python.c 18 Mar 2011 08:44:47 -0000 1.63
+++ gdb/python/python.c 28 Mar 2011 07:43:36 -0000
@@ -811,8 +811,9 @@

/* 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. */
+/*static*/ struct objfile *gdbpy_current_objfile;

/* Set the current objfile to OBJFILE and then read STREAM,FILE as
Python code. */
@@ -1074,6 +1075,7 @@
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 = []");