This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[python] [patch] PR python/12656 (API for special blocks)
- From: Phil Muldoon <pmuldoon at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Fri, 07 Oct 2011 18:02:15 +0100
- Subject: [python] [patch] PR python/12656 (API for special blocks)
- Reply-to: pmuldoon at redhat dot com
This patch addresses PR python/12656. It allows the user to determine if
a given gdb.Block is the static block, or the global block.
Additionally I added two new APIs to actually get the global/static
blocks on behalf of the user.
I also, because the global/static GDB fetch methods use const struct
*block, changed the Python code to use consts. This required some minor
refactoring both inside and outside the Python API code.
Ok?
Cheers,
Phil
--
2011-10-07 Phil Muldoon <pmuldoon@redhat.com>
PR python/12656
* python/py-frame.c (frapy_read_var): Use const struct *block.
* python/py-type.c (typy_lookup_typename): Likewise.
(typy_lookup_type): Likewise.
(typy_legacy_template_argument): Likewise.
(typy_template_argument): Likewise.
(gdbpy_lookup_type): Likewise.
* python/py-symbol.c (gdbpy_lookup_symbol): Likewise.
* python/py-block.c (blpy_block_object): Likewise.
(blpy_iter): Likewise.
(blpy_get_start): Likewise.
(blpy_get_end): Likewise.
(blpy_get_function): Likewise.
(blpy_get_superblock): Likewise.
(set_block): Likewise.
(block_to_block_object): Likewise.
(block_object_to_block): Likewise.
(blpy_is_valid): Likewise.
(blpy_get_global_block): New function.
(blpy_get_static_block): New function.
(blpy_is_global): New function.
(blpy_is_static): New function.
* blockframe.c (block_innermost_frame): Likewise.
* valops.c (value_of_variable): Likewise.
* frame.h: Update prototypes.
* python/python-internal.h: Likewise.
* value.h: Likewise.
2011-10-07 Phil Muldoon <pmuldoon@redhat.com>
PR python/12656
* gdb.texinfo (Blocks In Python): Document is_static, is_global,
global_block, static_block function.
2011-10-07 Phil Muldoon <pmuldoon@redhat.com>
PR python/12656
* gdb.python/py-block.exp: Add is_global, is_static, static_block,
global_block tests.
--
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 3b546a7..ef53a3d 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -358,7 +358,7 @@ find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
if there is no such frame. If BLOCK is NULL, just return NULL. */
struct frame_info *
-block_innermost_frame (struct block *block)
+block_innermost_frame (const struct block *block)
{
struct frame_info *frame;
CORE_ADDR start;
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index bb6e43c..f07c912 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -23196,6 +23196,15 @@ the time the method is called. This method is also made available to
the Python iterator object that @code{gdb.Block} provides in an iteration
context and via the Python @code{iter} built-in function.
@end defun
+@defun Block.is_global ()
+Returns @code{True} if the @code{gdb.Block} object is the global block
+for the inferior, @code{False} if not.
+@end defun
+@defun Block.is_static ()
+Returns @code{True} if the @code{gdb.Block} object is the static block
+for the inferior, @code{False} if not.
+@end defun
+
@end table
A @code{gdb.Block} object has the following attributes:
@@ -23219,6 +23228,17 @@ attribute is not writable.
The block containing this block. If this parent block does not exist,
this attribute holds @code{None}. This attribute is not writable.
@end defvar
+
+@defvar Block.global_block
+The global block associated with this block. This attribute is not
+writable.
+@end defvar
+
+@defvar Block.static_block
+The static block associated with this block. This attribute is not
+writable.
+@end defvar
+
@end table
@node Symbols In Python
diff --git a/gdb/frame.h b/gdb/frame.h
index a2052c0..0738264 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -689,7 +689,7 @@ extern void print_stack_frame (struct frame_info *, int print_level,
extern void print_frame_info (struct frame_info *, int print_level,
enum print_what print_what, int args);
-extern struct frame_info *block_innermost_frame (struct block *);
+extern struct frame_info *block_innermost_frame (const struct block *);
extern int deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc);
diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
index 08d4455..5ef7d2e 100644
--- a/gdb/python/py-block.c
+++ b/gdb/python/py-block.c
@@ -28,7 +28,7 @@
typedef struct blpy_block_object {
PyObject_HEAD
/* The GDB block structure that represents a frame's code block. */
- struct block *block;
+ const struct block *block;
/* The backing object file. There is no direct relationship in GDB
between a block and an object file. When a block is created also
store a pointer to the object file for later use. */
@@ -50,7 +50,7 @@ typedef struct {
/* Pointer back to the original source block object. Needed to
check if the block is still valid, and has not been invalidated
when an object file has been freed. */
- struct blpy_block_object *source;
+ const struct blpy_block_object *source;
} block_syms_iterator_object;
/* Require a valid block. All access to block_object->block should be
@@ -85,7 +85,7 @@ static PyObject *
blpy_iter (PyObject *self)
{
block_syms_iterator_object *block_iter_obj;
- struct block *block = NULL;
+ const struct block *block = NULL;
BLPY_REQUIRE_VALID (self, block);
@@ -105,7 +105,7 @@ blpy_iter (PyObject *self)
static PyObject *
blpy_get_start (PyObject *self, void *closure)
{
- struct block *block = NULL;
+ const struct block *block = NULL;
BLPY_REQUIRE_VALID (self, block);
@@ -115,7 +115,7 @@ blpy_get_start (PyObject *self, void *closure)
static PyObject *
blpy_get_end (PyObject *self, void *closure)
{
- struct block *block = NULL;
+ const struct block *block = NULL;
BLPY_REQUIRE_VALID (self, block);
@@ -126,7 +126,7 @@ static PyObject *
blpy_get_function (PyObject *self, void *closure)
{
struct symbol *sym;
- struct block *block = NULL;
+ const struct block *block;
BLPY_REQUIRE_VALID (self, block);
@@ -140,8 +140,8 @@ blpy_get_function (PyObject *self, void *closure)
static PyObject *
blpy_get_superblock (PyObject *self, void *closure)
{
- struct block *block = NULL;
- struct block *super_block = NULL;
+ const struct block *block;
+ const struct block *super_block;
block_object *self_obj = (block_object *) self;
BLPY_REQUIRE_VALID (self, block);
@@ -153,6 +153,47 @@ blpy_get_superblock (PyObject *self, void *closure)
Py_RETURN_NONE;
}
+/* Return the global block associated to this block. */
+
+static PyObject *
+blpy_get_global_block (PyObject *self, void *closure)
+{
+ const struct block *block;
+ const struct block *global_block;
+ block_object *self_obj = (block_object *) self;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ global_block = block_global_block (block);
+
+ return block_to_block_object (global_block,
+ self_obj->objfile);
+
+}
+
+/* Return the static block associated to this block. Return None
+ if we cannot get the static block (this is the global block). */
+
+static PyObject *
+blpy_get_static_block (PyObject *self, void *closure)
+{
+ const struct block *block;
+ const struct block *static_block;
+ block_object *self_obj = (block_object *) self;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ if (BLOCK_SUPERBLOCK (block) == NULL)
+ {
+ Py_INCREF (Py_None);
+ return Py_None;
+ }
+
+ static_block = block_static_block (block);
+
+ return block_to_block_object (static_block, self_obj->objfile);
+}
+
static void
blpy_dealloc (PyObject *obj)
{
@@ -176,7 +217,7 @@ blpy_dealloc (PyObject *obj)
with the life-cycle of the object file associated with this
block, if needed. */
static void
-set_block (block_object *obj, struct block *block,
+set_block (block_object *obj, const struct block *block,
struct objfile *objfile)
{
obj->block = block;
@@ -196,7 +237,7 @@ set_block (block_object *obj, struct block *block,
/* Create a new block object (gdb.Block) that encapsulates the struct
block object from GDB. */
PyObject *
-block_to_block_object (struct block *block, struct objfile *objfile)
+block_to_block_object (const struct block *block, struct objfile *objfile)
{
block_object *block_obj;
@@ -208,7 +249,7 @@ block_to_block_object (struct block *block, struct objfile *objfile)
}
/* Return struct block reference that is wrapped by this object. */
-struct block *
+const struct block *
block_object_to_block (PyObject *obj)
{
if (! PyObject_TypeCheck (obj, &block_object_type))
@@ -269,7 +310,7 @@ blpy_block_syms_dealloc (PyObject *obj)
static PyObject *
blpy_is_valid (PyObject *self, PyObject *args)
{
- struct block *block;
+ const struct block *block;
block = block_object_to_block (self);
if (block == NULL)
@@ -278,6 +319,39 @@ blpy_is_valid (PyObject *self, PyObject *args)
Py_RETURN_TRUE;
}
+/* Implementation of gdb.Block.is_global (self) -> Boolean.
+ Returns True if this block object is a global block. */
+
+static PyObject *
+blpy_is_global (PyObject *self, PyObject *args)
+{
+ const struct block *block;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ if (BLOCK_SUPERBLOCK (block))
+ Py_RETURN_FALSE;
+
+ Py_RETURN_TRUE;
+}
+
+/* Implementation of gdb.Block.is_static (self) -> Boolean.
+ Returns True if this block object is a static block. */
+
+static PyObject *
+blpy_is_static (PyObject *self, PyObject *args)
+{
+ const struct block *block;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ if (BLOCK_SUPERBLOCK (block) != NULL
+ && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
+ Py_RETURN_TRUE;
+
+ Py_RETURN_FALSE;
+}
+
/* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
Returns True if this block iterator object still exists in GDB */
@@ -376,6 +450,13 @@ static PyMethodDef block_object_methods[] = {
{ "is_valid", blpy_is_valid, METH_NOARGS,
"is_valid () -> Boolean.\n\
Return true if this block is valid, false if not." },
+ { "is_global", blpy_is_global, METH_NOARGS,
+ "is_global () -> Boolean.\n\
+Return true if this block is the global block, false if not." },
+ { "is_static", blpy_is_static, METH_NOARGS,
+ "is_static () -> Boolean.\n\
+Return true if this block is the static block, false if not." },
+
{NULL} /* Sentinel */
};
@@ -386,6 +467,10 @@ static PyGetSetDef block_object_getset[] = {
"Symbol that names the block, or None.", NULL },
{ "superblock", blpy_get_superblock, NULL,
"Block containing the block, or None.", NULL },
+ { "global_block", blpy_get_global_block, NULL,
+ "Block containing the global block.", NULL },
+ { "static_block", blpy_get_static_block, NULL,
+ "Block containing the static block.", NULL },
{ NULL } /* Sentinel */
};
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 9143367..6520ad3 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -411,7 +411,7 @@ frapy_read_var (PyObject *self, PyObject *args)
else if (gdbpy_is_string (sym_obj))
{
char *var_name;
- struct block *block = NULL;
+ const struct block *block = NULL;
struct cleanup *cleanup;
volatile struct gdb_exception except;
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index 8a8510e..300b94e 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -276,7 +276,7 @@ gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
static char *keywords[] = { "name", "block", "domain", NULL };
struct symbol *symbol;
PyObject *block_obj = NULL, *ret_tuple, *sym_obj, *bool_obj;
- struct block *block = NULL;
+ const struct block *block ;
if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name,
&block_object_type, &block_obj, &domain))
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index c7fd25b..77ce8f2 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -575,7 +575,7 @@ typy_get_sizeof (PyObject *self, void *closure)
}
static struct type *
-typy_lookup_typename (const char *type_name, struct block *block)
+typy_lookup_typename (const char *type_name, const struct block *block)
{
struct type *type = NULL;
volatile struct gdb_exception except;
@@ -605,7 +605,7 @@ typy_lookup_typename (const char *type_name, struct block *block)
static struct type *
typy_lookup_type (struct demangle_component *demangled,
- struct block *block)
+ const struct block *block)
{
struct type *type;
char *type_name;
@@ -650,7 +650,7 @@ typy_lookup_type (struct demangle_component *demangled,
versions of GCC, that do not emit DW_TAG_template_*. */
static PyObject *
-typy_legacy_template_argument (struct type *type, struct block *block,
+typy_legacy_template_argument (struct type *type, const struct block *block,
int argno)
{
int i;
@@ -715,7 +715,7 @@ typy_template_argument (PyObject *self, PyObject *args)
{
int argno;
struct type *type = ((type_object *) self)->type;
- struct block *block = NULL;
+ const struct block *block = NULL;
PyObject *block_obj = NULL;
struct symbol *sym;
struct value *val = NULL;
@@ -1311,7 +1311,7 @@ gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
const char *type_name = NULL;
struct type *type = NULL;
PyObject *block_obj = NULL;
- struct block *block = NULL;
+ const struct block *block = NULL;
if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O", keywords,
&type_name, &block_obj))
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 71325e2..e593612 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -164,7 +164,8 @@ char *gdbpy_parse_command_name (const char *name,
PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal);
PyObject *symtab_to_symtab_object (struct symtab *symtab);
PyObject *symbol_to_symbol_object (struct symbol *sym);
-PyObject *block_to_block_object (struct block *block, struct objfile *objfile);
+PyObject *block_to_block_object (const struct block *block,
+ struct objfile *objfile);
PyObject *value_to_value_object (struct value *v);
PyObject *type_to_type_object (struct type *);
PyObject *frame_info_to_frame_object (struct frame_info *frame);
@@ -180,7 +181,7 @@ thread_object *find_thread_object (ptid_t ptid);
PyObject *find_inferior_object (int pid);
PyObject *inferior_to_inferior_object (struct inferior *inferior);
-struct block *block_object_to_block (PyObject *obj);
+const struct block *block_object_to_block (PyObject *obj);
struct symbol *symbol_object_to_symbol (PyObject *obj);
struct value *value_object_to_value (PyObject *self);
struct value *convert_value_from_python (PyObject *obj);
diff --git a/gdb/testsuite/gdb.python/py-block.exp b/gdb/testsuite/gdb.python/py-block.exp
index 98b89d9..7fc8433 100644
--- a/gdb/testsuite/gdb.python/py-block.exp
+++ b/gdb/testsuite/gdb.python/py-block.exp
@@ -48,6 +48,17 @@ gdb_test "python print block.function" "None" "First anonymous block"
gdb_test "python print block.start" "${decimal}" "Check start not None"
gdb_test "python print block.end" "${decimal}" "Check end not None"
+# Test global/static blocks
+gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
+gdb_py_test_silent_cmd "python block = frame.block()" "Get block" 0
+gdb_test "python print block.is_global()" "False" "Not a global block"
+gdb_test "python print block.is_static()" "False" "Not a static block"
+gdb_py_test_silent_cmd "python gblock = block.global_block" "Get block" 1
+gdb_py_test_silent_cmd "python sblock = block.static_block" "Get block" 1
+gdb_test "python print gblock.is_global()" "True" "Is the global block"
+gdb_test "python print sblock.is_static()" "True" "Is the static block"
+
+
# Move up superblock(s) until we reach function block_func.
gdb_test_no_output "python block = block.superblock" "Get superblock"
gdb_test "python print block.function" "None" "Second anonymous block"
@@ -79,3 +90,4 @@ gdb_test "python print block.is_valid()" "False" \
"Check block validity"
gdb_test "python print block_iter.is_valid()" "False" \
"Check block validity"
+
diff --git a/gdb/valops.c b/gdb/valops.c
index 32d71cd..3a594c6 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1486,7 +1486,7 @@ value_repeat (struct value *arg1, int count)
}
struct value *
-value_of_variable (struct symbol *var, struct block *b)
+value_of_variable (struct symbol *var, const struct block *b)
{
struct frame_info *frame;
diff --git a/gdb/value.h b/gdb/value.h
index 5d61a0b..5541451 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -493,7 +493,7 @@ extern struct value *value_from_register (struct type *type, int regnum,
extern CORE_ADDR address_from_register (struct type *type, int regnum,
struct frame_info *frame);
-extern struct value *value_of_variable (struct symbol *var, struct block *b);
+extern struct value *value_of_variable (struct symbol *var, const struct block *b);
extern struct value *address_of_variable (struct symbol *var, struct block *b);