From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30154 invoked by alias); 7 Oct 2011 17:02:41 -0000 Received: (qmail 30136 invoked by uid 22791); 7 Oct 2011 17:02:38 -0000 X-SWARE-Spam-Status: No, hits=-6.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_BJ,TW_BL X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 07 Oct 2011 17:02:17 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p97H2H8g027284 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 7 Oct 2011 13:02:17 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p97H2Fv0021027 for ; Fri, 7 Oct 2011 13:02:16 -0400 From: Phil Muldoon To: gdb-patches@sourceware.org Subject: [python] [patch] PR python/12656 (API for special blocks) Reply-to: pmuldoon@redhat.com X-URL: http://www.redhat.com Date: Fri, 07 Oct 2011 17:02:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-10/txt/msg00204.txt.bz2 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 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 PR python/12656 * gdb.texinfo (Blocks In Python): Document is_static, is_global, global_block, static_block function. 2011-10-07 Phil Muldoon 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);