[RFC - Python Scripting] New method gdb.Symtab.blocks_iterator - docs included
Siva Chandra
sivachandra@google.com
Mon Apr 9 18:34:00 GMT 2012
Hello,
While the work on Objfile.symtabs (or Objfile.iterator) is pending, I
want to complete the API for the exploratory path Objfile => Symtabs
=> Blocks => Symbols. This patch adds the missing link Symtabs =>
Blocks. The method Symtab.blocks_iterator returns an iterator to
iterate over the scope blocks of a symtab. The patch is attached and
the ChangeLog is as follows:
Code -
2012-04-09 Siva Chandra Reddy <sivachandra@google.com>
Add a new method gdb.Symtab.blocks_iterator to iterate
over the scope blocks of a symbol table.
* NEWS (Python scripting): Add entry about the new method.
* python/py-symtab.c (symtab_blocks_iterator_object): New
iterator type to iterate over the scope blocks of a symtab.
(stpy_blocks_iterator): New function which implements the
new method.
(symtab_blocks_iterator_dealloc): New function which serves
as the tp_dealloc function for symtab_blocks_iterator_object.
(symtab_blocks_iterator_iter): New function which serves as
the tp_iter function for symtab_blocks_iterator_object.
(symtab_blocks_iterator_iternext): New function which serves as
the tp_iternext function for symtab_blocks_iterator_object.
(gdbpy_initialize_symtabs): Add initializations for the new
iterator type.
Docs -
2012-04-09 Siva Chandra Reddy <sivachandra@google.com>
* gdb.texinfo (Symbol Tables In Python): Add description about
the new method gdb.Symtab.blocks_iterator.
Tests -
2012-04-09 Siva Chandra Reddy <sivachandra@google.com>
* gdb.python/py-symtab.exp: Add tests to test the new method
gdb.Symtab.blocks_iterator.
Thanks,
Siva Chandra
-------------- next part --------------
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.506
diff -c -p -r1.506 NEWS
*** NEWS 2 Apr 2012 07:32:31 -0000 1.506
--- NEWS 9 Apr 2012 17:59:49 -0000
***************
*** 32,37 ****
--- 32,41 ----
** A new method 'referenced_value' on gdb.Value objects which can
dereference pointer as well as C++ reference values.
+ ** A new method 'blocks_iterator' on gdb.Symtab objects which returns
+ an iterator to iterate over the scope blocks (gdb.Block objects) of
+ the symbol table (gdb.Symtab object).
+
* GDBserver now supports stdio connections.
E.g. (gdb) target remote | ssh myhost gdbserver - hello
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.939
diff -c -p -r1.939 gdb.texinfo
*** doc/gdb.texinfo 28 Mar 2012 21:31:46 -0000 1.939
--- doc/gdb.texinfo 9 Apr 2012 18:00:12 -0000
*************** if it is invalid at the time the method
*** 24392,24397 ****
--- 24392,24403 ----
@defun Symtab.fullname ()
Return the symbol table's source absolute file name.
@end defun
+
+ @defun Symtab.blocks_iterator ()
+ Return an iterator with which the user can iterate over the symbol
+ scope blocks (@code{gdb.Block} objects) of the symbol table
+ (@code{gdb.Symtab} object). @xref{Blocks In Python}.
+ @end defun
@end table
@node Breakpoints In Python
Index: python/py-symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-symtab.c,v
retrieving revision 1.8
diff -c -p -r1.8 py-symtab.c
*** python/py-symtab.c 4 Jan 2012 08:17:25 -0000 1.8
--- python/py-symtab.c 9 Apr 2012 18:00:13 -0000
***************
*** 20,25 ****
--- 20,26 ----
#include "defs.h"
#include "charset.h"
#include "symtab.h"
+ #include "block.h"
#include "source.h"
#include "python-internal.h"
#include "objfiles.h"
*************** typedef struct stpy_symtab_object {
*** 36,42 ****
--- 37,63 ----
struct stpy_symtab_object *next;
} symtab_object;
+ /* Iterator object type whose instance serves as an iterator over the
+ scope blocks in the underlying symtab of a symtab_object. */
+
+ typedef struct stpy_blocks_iterator_object
+ {
+ PyObject_HEAD
+
+ /* A reference to the symtab_object from which this iterator was
+ created. */
+
+ symtab_object *symtab_obj;
+
+ /* Index of the block object currently pointed to by the
+ iterator. */
+
+ int iter_index;
+ } symtab_blocks_iterator_object;
+
static PyTypeObject symtab_object_type;
+ static PyTypeObject symtab_blocks_iterator_object_type;
+
static const struct objfile_data *stpy_objfile_data_key;
/* Require a valid symbol table. All access to symtab_object->symtab
*************** stpy_is_valid (PyObject *self, PyObject
*** 153,158 ****
--- 174,205 ----
Py_RETURN_TRUE;
}
+ /* Implementation of gdb.Symtab.blocks_iterator (self) -> iterator.
+ Returns an iterator with which a user can iterator over the scope
+ blocks (gdb.Block objects) of the underlying symtab. */
+
+ static PyObject *
+ stpy_blocks_iterator (PyObject *self, PyObject *args)
+ {
+ struct symtab *symtab = NULL;
+ symtab_blocks_iterator_object *iter = NULL;
+ symtab_object *symtab_obj = (symtab_object *) self;
+
+ STPY_REQUIRE_VALID (self, symtab);
+ /* The iterator holds a reference to the symtab_object. */
+ Py_INCREF (self);
+
+ iter = PyObject_New (symtab_blocks_iterator_object,
+ &symtab_blocks_iterator_object_type);
+ if (iter)
+ {
+ iter->symtab_obj = symtab_obj;
+ iter->iter_index = 0;
+ }
+
+ return (PyObject *) iter;
+ }
+
static PyObject *
salpy_str (PyObject *self)
{
*************** stpy_dealloc (PyObject *obj)
*** 193,199 ****
symtab->symtab = NULL;
}
-
static PyObject *
salpy_get_pc (PyObject *self, void *closure)
{
--- 240,245 ----
*************** del_objfile_sal (struct objfile *objfile
*** 431,436 ****
--- 477,540 ----
}
}
+ /* The tp_dealloc function of symtab_blocks_iterator_object_type. */
+
+ static void
+ symtab_blocks_iterator_dealloc (PyObject *self)
+ {
+ symtab_blocks_iterator_object *iter;
+
+ /* Decrement the reference to the symtab_object. */
+ if (self)
+ {
+ iter = (symtab_blocks_iterator_object *) self;
+ Py_DECREF ((PyObject *) iter->symtab_obj);
+ }
+ }
+
+ /* The tp_iter function of symtab_blocks_iterator_object_type. */
+
+ static PyObject *
+ symtab_blocks_iterator_iter (PyObject *self)
+ {
+ Py_INCREF (self);
+ return self;
+ }
+
+ /* The tp_iternext function of symtab_blocks_iterator_object_type. */
+
+ static PyObject *
+ symtab_blocks_iterator_iternext (PyObject *self)
+ {
+ PyObject *block_object;
+ symtab_blocks_iterator_object *iter;
+ symtab_object *symtab_obj;
+ struct symtab *symtab;
+ struct block *block;
+
+ if (! self)
+ return NULL;
+
+ iter = (symtab_blocks_iterator_object *) self;
+ symtab_obj = iter->symtab_obj;
+ STPY_REQUIRE_VALID ((PyObject *) symtab_obj, symtab);
+
+ if (iter->iter_index >= symtab->blockvector->nblocks)
+ return NULL;
+
+ block = symtab->blockvector->block[iter->iter_index];
+ block_object = block_to_block_object (block, symtab->objfile);
+ if (! block_object)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Unable to get the next gdb.Block object."));
+ return NULL;
+ }
+
+ (iter->iter_index)++;
+ return block_object;
+ }
+
void
gdbpy_initialize_symtabs (void)
{
*************** gdbpy_initialize_symtabs (void)
*** 442,447 ****
--- 546,555 ----
if (PyType_Ready (&sal_object_type) < 0)
return;
+ symtab_blocks_iterator_object_type.tp_new = PyType_GenericNew;
+ if (PyType_Ready (&symtab_blocks_iterator_object_type) < 0)
+ return;
+
/* Register an objfile "free" callback so we can properly
invalidate symbol tables, and symbol table and line data
structures when an object file that is about to be
*************** gdbpy_initialize_symtabs (void)
*** 458,463 ****
--- 566,575 ----
Py_INCREF (&sal_object_type);
PyModule_AddObject (gdb_module, "Symtab_and_line",
(PyObject *) &sal_object_type);
+
+ Py_INCREF (&symtab_blocks_iterator_object_type);
+ PyModule_AddObject (gdb_module, "BlockIterator",
+ (PyObject *) &symtab_blocks_iterator_object_type);
}
*************** Return true if this symbol table is vali
*** 477,482 ****
--- 589,598 ----
{ "fullname", stpy_fullname, METH_NOARGS,
"fullname () -> String.\n\
Return the symtab's full source filename." },
+ { "blocks_iterator", stpy_blocks_iterator, METH_NOARGS,
+ "blocks_iterator () -> iterator.\n\
+ Return an iterator over the scope blocks (gdb.Block objects) of the\n\
+ underlying Symtab." },
{NULL} /* Sentinel */
};
*************** static PyTypeObject sal_object_type = {
*** 562,564 ****
--- 678,711 ----
0, /*tp_members */
sal_object_getset /*tp_getset */
};
+
+ static PyTypeObject symtab_blocks_iterator_object_type = {
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.BlockIterator", /*tp_name*/
+ sizeof (symtab_blocks_iterator_object), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ symtab_blocks_iterator_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
+ "Iterator over GDB blocks", /*tp_doc */
+ 0, /*tp_traverse */
+ 0, /*tp_clear */
+ 0, /*tp_richcompare */
+ 0, /*tp_weaklistoffset */
+ symtab_blocks_iterator_iter, /*tp_iter */
+ symtab_blocks_iterator_iternext, /*tp_iternext */
+ };
Index: testsuite/gdb.python/py-symtab.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-symtab.exp,v
retrieving revision 1.8
diff -c -p -r1.8 py-symtab.exp
*** testsuite/gdb.python/py-symtab.exp 7 Feb 2012 19:42:27 -0000 1.8
--- testsuite/gdb.python/py-symtab.exp 9 Apr 2012 18:00:14 -0000
*************** load_lib gdb-python.exp
*** 21,37 ****
set testfile "py-symbol"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
! if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
! untested "Couldn't compile ${srcfile}"
return -1
}
- # Start with a fresh gdb.
- gdb_exit
- gdb_start
- gdb_reinitialize_dir $srcdir/$subdir
- gdb_load ${binfile}
-
# Skip all tests if Python scripting is not enabled.
if { [skip_python_tests] } { continue }
--- 21,31 ----
set testfile "py-symbol"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
!
! if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
return -1
}
# Skip all tests if Python scripting is not enabled.
if { [skip_python_tests] } { continue }
*************** if ![runto_main] then {
*** 41,54 ****
}
global hex decimal
-
- # Setup and get the symbol table.
set line_no [gdb_get_line_number "Block break here."]
! gdb_breakpoint $line_no
! gdb_continue_to_breakpoint "Block break here."
! gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
! gdb_py_test_silent_cmd "python sal = frame.find_sal()" "Get block" 0
! gdb_py_test_silent_cmd "python symtab = sal.symtab" "Get block" 0
# Test sal.
gdb_test "python print sal.symtab" ".*gdb.python/py-symbol.c.*" "Test symtab"
--- 35,56 ----
}
global hex decimal
set line_no [gdb_get_line_number "Block break here."]
!
! # Proc to setup and get the symbol table in the Python environment.
! proc setup_python_env { line_no } {
! gdb_breakpoint $line_no
! gdb_continue_to_breakpoint "Block break here."
! gdb_py_test_silent_cmd "python def func_symbol(block): return block.function" "Define a func to get the function symbols" "0"
! gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
! gdb_py_test_silent_cmd "python sal = frame.find_sal()" "Get block" 0
! gdb_py_test_silent_cmd "python symtab = sal.symtab" "Get block" 0
! gdb_py_test_silent_cmd "python block_list = list(symtab.blocks_iterator())" "Create a list of blocks" 0
! gdb_py_test_silent_cmd "python func_symbols = map(func_symbol, block_list)" "Create a list of function symbols" 0
! gdb_py_test_silent_cmd "python func_names = map(str, func_symbols)" "Create a list of function names" 0
! }
!
! setup_python_env $line_no
# Test sal.
gdb_test "python print sal.symtab" ".*gdb.python/py-symbol.c.*" "Test symtab"
*************** gdb_test "python print symtab.filename"
*** 61,69 ****
--- 63,90 ----
gdb_test "python print symtab.objfile" "<gdb.Objfile object at ${hex}>" "Test symtab.objfile"
gdb_test "python print symtab.fullname()" "testsuite/gdb.python/py-symbol.c.*" "Test symtab.fullname"
gdb_test "python print symtab.is_valid()" "True" "Test symtab.is_valid()"
+ gdb_test "python print 'func' in func_names" "True" "Test that there is a symbol for the function func"
+ gdb_test "python print 'main' in func_names" "True" "Test that there is a symbol for the function main"
+
# Test is_valid when the objfile is unloaded. This must be the last
# test as it unloads the object file in GDB.
gdb_unload
gdb_test "python print sal.is_valid()" "False" "Test sal.is_valid"
gdb_test "python print symtab.is_valid()" "False" "Test symtab.is_valid()"
+
+ # Compile the source file as a C++ file and test again.
+ if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}] } {
+ return -1
+ }
+
+ if ![runto_main] {
+ return -1
+ }
+
+ setup_python_env $line_no
+
+ gdb_test "python print 'func(int)' in func_names" "True" "Test that there is a symbol for the function func"
+ gdb_test "python print 'main(int, char**)' in func_names" "True" "Test that there is a symbol for the function main"
+ gdb_test "python print 'SimpleClass::seti(int)' in func_names" "True" "Test that the function SimpleClass::seti(int) is present"
+ gdb_test "python print 'SimpleClass::valueofi()' in func_names" "True" "Test that the function SimpleClass::valueofi() is present"
More information about the Gdb-patches
mailing list