From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7302 invoked by alias); 7 Apr 2009 20:28:42 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 7277 invoked by uid 306); 7 Apr 2009 20:28:40 -0000 Date: Tue, 07 Apr 2009 20:28:00 -0000 Message-ID: <20090407202840.7262.qmail@sourceware.org> From: tromey@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-tromey-python: gdb X-Git-Refname: refs/heads/archer-tromey-python X-Git-Reftype: branch X-Git-Oldrev: 27864e441f63a596e0c6896bf26e5594949332a3 X-Git-Newrev: 1f080e897996d60ab7fde20423e2947512115667 X-SW-Source: 2009-q2/txt/msg00011.txt.bz2 List-Id: The branch, archer-tromey-python has been updated via 1f080e897996d60ab7fde20423e2947512115667 (commit) from 27864e441f63a596e0c6896bf26e5594949332a3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 1f080e897996d60ab7fde20423e2947512115667 Author: Tom Tromey Date: Tue Apr 7 14:26:53 2009 -0600 gdb * python/python.c (GdbMethods): Add "lookup_type". * python/python-internal.h (gdbpy_lookup_type): Declare. * python/lib/gdb/libstdcxx/v6/printers.py: Update. * python/lib/gdb/command/pahole.py: Update. * python/python-value.c (value_object) : New field. (valpy_dealloc): Destroy type. (valpy_new): Initialize new field. (valpy_get_type): Rename. Now a getter. (value_to_value_object): Initialize new field. (value_object_getset): Add "type". (value_object_methods): Remove "type". * python/python-type.c (field_dealloc): Call tp_free. (typy_lookup_typename): Use GDB_PY_HANDLE_EXCEPTION. (typy_new): Make name argument mandatory. (typy_get_code): Rename. Now a getter. (typy_get_tag): Likewise. (typy_get_sizeof): Likewise. Don't throw an exception. (type_object_getset): New global. (type_object_type): Use it. (type_object_methods): Remove getters. (gdbpy_lookup_type): Move. Rename from typy_new. gdb/doc * gdb.texinfo (Types In Python): Rename and update. (Values From Inferior): "type" is now an attribute. gdb/testsuite * gdb.python/python-value.exp: Update. * gdb.python/python-template.exp: Update. * gdb.python/python-prettyprint.py: Update. * gdb.python/find.exp: Update. ----------------------------------------------------------------------- Summary of changes: gdb/doc/gdb.texinfo | 105 +++++++++---------- gdb/python/lib/gdb/command/pahole.py | 22 ++--- gdb/python/lib/gdb/libstdcxx/v6/printers.py | 50 +++++----- gdb/python/python-internal.h | 1 + gdb/python/python-type.c | 134 +++++++++++++----------- gdb/python/python-value.c | 26 ++++- gdb/python/python.c | 5 + gdb/testsuite/gdb.python/find.exp | 8 +- gdb/testsuite/gdb.python/python-prettyprint.py | 8 +- gdb/testsuite/gdb.python/python-template.exp | 4 +- gdb/testsuite/gdb.python/python-value.exp | 4 +- 11 files changed, 196 insertions(+), 171 deletions(-) First 500 lines of diff: diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 4c92495..8b1b944 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -18135,7 +18135,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown. * Exception Handling:: * Auto-loading:: Automatically loading Python code. * Values From Inferior:: Python representation of values. -* Types From Inferior:: Python representation of types. +* Types In Python:: Python representation of types. * Pretty Printing:: Pretty-printing values. * Threads In Python:: Accessing inferior threads from Python. * Commands In Python:: Implementing new commands in Python. @@ -18393,17 +18393,22 @@ Again, @code{bar} will also be a @code{gdb.Value} object. The following attributes are provided: @table @code -@defmethod Value address +@defivar Value address If this object is addressable, this read-only attribute holds a @code{gdb.Value} object representing the address. Otherwise, this attribute holds @code{None}. -@end defmethod +@end defivar @cindex optimized out value in Python -@defmethod Value is_optimized_out +@defivar Value is_optimized_out This read-only boolean attribute is true if the compiler optimized out this value, thus it is not available for fetching from the inferior. -@end defmethod +@end defivar + +@defivar Value type +The type of this @code{gdb.Value}. The result is a @code{gdb.Type} +object. +@end defivar @end table The following methods are provided: @@ -18463,43 +18468,62 @@ will be used, if the current language is able to supply one. The optional @var{errors} argument is the same as the corresponding argument to Python's @code{string.decode} method. @end defmethod - -@defmethod Value type -Return the type of this @code{gdb.Value}. The result is a -@code{gdb.Type} object. -@end defmethod @end table -@node Types From Inferior -@subsubsection Types From Inferior +@node Types In Python +@subsubsection Types In Python +@cindex types in Python +@cindex Python, working with types -@cindex gdb.Type +@tindex gdb.Type @value{GDBN} represents types from the inferior using the class @code{gdb.Type}. -The following methods are provided: - -@table @code -@defmethod Type Type [name [block]] -Construct a new instance of @code{gdb.Type}. +The following type-related functions are available in the @code{gdb} +module: -If @var{name} is given, it specifies the name of a type to look up in -the inferior. +@findex gdb.lookup_type +@defun lookup_type name [block] +This function looks up a type by name. @var{name} is the name of the +type to look up. It must be a string. If @var{block} is given, then @var{name} is looked up in that scope. Otherwise, it is searched for globally. -@end defmethod -@defmethod Type code -Return the type code for this type. The type code will be one of the +Ordinarily, this function will return an instance of @code{gdb.Type}. +If the named type cannot be found, it will throw an exception. +@end defun + +An instance of @code{Type} has the following attributes: + +@table @code +@defivar Type code +The type code for this type. The type code will be one of the @code{TYPE_CODE_} constants defined below. -@end defmethod +@end defivar +@defivar Type sizeof +The size of this type, in target @code{char} units. Usually, a +target's @code{char} type will be an 8-bit byte. However, on some +unusual platforms, this type may have a different size. +@end defivar + +@defivar Type tag +The tag name for this type. The tag name is the name after +@code{struct}, @code{union}, or @code{enum} in C; not all languages +have this concept. If this type has no tag name, then @code{None} is +returned. +@end defivar +@end table + +The following methods are provided: + +@table @code @defmethod Type fields For structure and union types, this method returns the fields. Range types have two fields, the minimum and maximum values. Enum types have one field per enum constant. Function and method types have one -field per parameter. The base types of C++ classes are also +field per parameter. The base types of C@t{++} classes are also represented as fields. If the type has no fields, or does not fit into one of these categories, an empty sequence will be returned. @@ -18549,24 +18573,11 @@ Return a new @code{gdb.Type} object which represents a reference to this type. @end defmethod -@defmethod Type sizeof -Return the size of this type, in target @code{char} units. Usually, a -target's @code{char} type will be an 8-bit byte. However, on some -unusual platforms, this type may have a different size. -@end defmethod - @defmethod Type strip_typedefs Return a new @code{gdb.Type} that represents the real type, after removing all layers of typedefs. @end defmethod -@defmethod Type tag -Return the tag name for this type. The tag name is the name after -@code{struct}, @code{union}, or @code{enum} in C; not all languages -have this concept. If this type has no tag name, then @code{None} is -returned. -@end defmethod - @defmethod Type target Return a new @code{gdb.Type} object which represents the target type of this type. @@ -18626,8 +18637,7 @@ The type is an enum. @findex TYPE_CODE_FLAGS @findex gdb.TYPE_CODE_FLAGS @item TYPE_CODE_FLAGS -A bit flags type. -@c FIXME: what is this? +A bit flags type, used for things such as status registers. @findex TYPE_CODE_FUNC @findex gdb.TYPE_CODE_FUNC @@ -18678,7 +18688,7 @@ An unknown or erroneous type. @findex TYPE_CODE_METHOD @findex gdb.TYPE_CODE_METHOD @item TYPE_CODE_METHOD -A C++ method type. +A method type, as found in C++ or Java. @findex TYPE_CODE_METHODPTR @findex gdb.TYPE_CODE_METHODPTR @@ -18715,19 +18725,6 @@ A complex float type. @item TYPE_CODE_TYPEDEF A typedef to some other type. -@findex TYPE_CODE_TEMPLATE -@findex gdb.TYPE_CODE_TEMPLATE -@item TYPE_CODE_TEMPLATE -A C++ template type. Note that this is not used for a template -instantiation; those appear as ordinary struct types. -@c FIXME I hope that is true - -@findex TYPE_CODE_TEMPLATE_ARG -@findex gdb.TYPE_CODE_TEMPLATE_ARG -@item TYPE_CODE_TEMPLATE_ARG -A C++ template argument. -@c FIXME: is this ever used? - @findex TYPE_CODE_NAMESPACE @findex gdb.TYPE_CODE_NAMESPACE @item TYPE_CODE_NAMESPACE diff --git a/gdb/python/lib/gdb/command/pahole.py b/gdb/python/lib/gdb/command/pahole.py index 569b816..21a0bf0 100644 --- a/gdb/python/lib/gdb/command/pahole.py +++ b/gdb/python/lib/gdb/command/pahole.py @@ -1,6 +1,6 @@ # pahole command for gdb -# Copyright (C) 2008 Free Software Foundation, Inc. +# Copyright (C) 2008, 2009 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 @@ -26,16 +26,10 @@ It prints the type and displays comments showing where holes are.""" super (Pahole, self).__init__ ("pahole", gdb.COMMAND_NONE, gdb.COMPLETE_SYMBOL) - @staticmethod - def strip (type): - while type.code () == gdb.TYPE_CODE_TYPEDEF: - type = type.target () - return type - def pahole (self, type, level, name): if name is None: name = '' - tag = type.tag () + tag = type.tag if tag is None: tag = '' print '%sstruct %s {' % (' ' * (2 * level), tag) @@ -45,7 +39,7 @@ It prints the type and displays comments showing where holes are.""" if not hasattr (field, ('bitpos')): continue - ftype = self.strip (field.type) + ftype = field.type.strip_typedefs() if bitpos != field.bitpos: hole = field.bitpos - bitpos @@ -55,13 +49,13 @@ It prints the type and displays comments showing where holes are.""" fieldsize = field.bitsize else: # TARGET_CHAR_BIT here... - fieldsize = 8 * ftype.sizeof () + fieldsize = 8 * ftype.sizeof # TARGET_CHAR_BIT print ' /* %3d %3d */' % (int (bitpos / 8), int (fieldsize / 8)), bitpos = bitpos + fieldsize - if ftype.code () == gdb.TYPE_CODE_STRUCT: + if ftype.code == gdb.TYPE_CODE_STRUCT: self.pahole (ftype, level + 1, field.name) else: print ' ' * (2 + 2 * level), @@ -71,9 +65,9 @@ It prints the type and displays comments showing where holes are.""" print '} %s' % name def invoke (self, arg, from_tty): - type = gdb.Type (arg) - type = self.strip (type) - if type.code () != gdb.TYPE_CODE_STRUCT: + type = gdb.lookup_type (arg) + type = type.strip_typedefs () + if type.code != gdb.TYPE_CODE_STRUCT: raise TypeError, '%s is not a struct type' % arg print ' ' * 14, self.pahole (type, 0, '') diff --git a/gdb/python/lib/gdb/libstdcxx/v6/printers.py b/gdb/python/lib/gdb/libstdcxx/v6/printers.py index 149f1dd..2bd2593 100644 --- a/gdb/python/lib/gdb/libstdcxx/v6/printers.py +++ b/gdb/python/lib/gdb/libstdcxx/v6/printers.py @@ -68,8 +68,8 @@ class StdListPrinter: self.val = val def children(self): - itype = self.val.type().template_argument(0) - nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer() + itype = self.val.type.template_argument(0) + nodetype = gdb.lookup_type('std::_List_node<%s>' % itype).pointer() return self._iterator(nodetype, self.val['_M_impl']['_M_node']) def to_string(self): @@ -84,8 +84,8 @@ class StdListIteratorPrinter: self.val = val def to_string(self): - itype = self.val.type().template_argument(0) - nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer() + itype = self.val.type.template_argument(0) + nodetype = gdb.lookup_type('std::_List_node<%s>' % itype).pointer() return self.val['_M_node'].cast(nodetype).dereference()['_M_data'] class StdSlistPrinter: @@ -113,8 +113,8 @@ class StdSlistPrinter: self.val = val def children(self): - itype = self.val.type().template_argument(0) - nodetype = gdb.Type('__gnu_cxx::_Slist_node<%s>' % itype).pointer() + itype = self.val.type.template_argument(0) + nodetype = gdb.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype).pointer() return self._iterator(nodetype, self.val) def to_string(self): @@ -129,8 +129,8 @@ class StdSlistIteratorPrinter: self.val = val def to_string(self): - itype = self.val.type().template_argument(0) - nodetype = gdb.Type('__gnu_cxx::_Slist_node<%s>' % itype).pointer() + itype = self.val.type.template_argument(0) + nodetype = gdb.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype).pointer() return self.val['_M_node'].cast(nodetype).dereference()['_M_data'] class StdVectorPrinter: @@ -243,8 +243,8 @@ class StdRbtreeIteratorPrinter: self.val = val def to_string (self): - valuetype = self.val.type().template_argument(0) - nodetype = gdb.Type('std::_Rb_tree_node < %s >' % valuetype) + valuetype = self.val.type.template_argument(0) + nodetype = gdb.lookup_type('std::_Rb_tree_node < %s >' % valuetype) nodetype = nodetype.pointer() return self.val.cast(nodetype).dereference()['_M_value_field'] @@ -283,9 +283,9 @@ class StdMapPrinter: return '%s with %d elements' % (self.typename, len (self.iter)) def children (self): - keytype = self.val.type().template_argument(0).const() - valuetype = self.val.type().template_argument(1) - nodetype = gdb.Type('std::_Rb_tree_node< std::pair< %s, %s > >' % (keytype, valuetype)) + keytype = self.val.type.template_argument(0).const() + valuetype = self.val.type.template_argument(1) + nodetype = gdb.lookup_type('std::_Rb_tree_node< std::pair< %s, %s > >' % (keytype, valuetype)) nodetype = nodetype.pointer() return self._iter (self.iter, nodetype) @@ -323,8 +323,8 @@ class StdSetPrinter: return '%s with %d elements' % (self.typename, len (self.iter)) def children (self): - keytype = self.val.type().template_argument(0) - nodetype = gdb.Type('std::_Rb_tree_node< %s >' % keytype).pointer() + keytype = self.val.type.template_argument(0) + nodetype = gdb.lookup_type('std::_Rb_tree_node< %s >' % keytype).pointer() return self._iter (self.iter, nodetype) class StdBitsetPrinter: @@ -340,18 +340,18 @@ class StdBitsetPrinter: def children (self): words = self.val['_M_w'] - wtype = words.type() + wtype = words.type # The _M_w member can be either an unsigned long, or an # array. This depends on the template specialization used. # If it is a single long, convert to a single element list. - if wtype.code () == gdb.TYPE_CODE_ARRAY: - tsize = wtype.target ().sizeof () + if wtype.code == gdb.TYPE_CODE_ARRAY: + tsize = wtype.target ().sizeof else: words = [words] - tsize = wtype.sizeof () + tsize = wtype.sizeof - nwords = wtype.sizeof() / tsize + nwords = wtype.sizeof / tsize result = [] byte = 0 while byte < nwords: @@ -401,8 +401,8 @@ class StdDequePrinter: def __init__(self, val): self.val = val - self.elttype = val.type().template_argument(0) - size = self.elttype.sizeof () + self.elttype = val.type.template_argument(0) + size = self.elttype.sizeof if size < 512: self.buffer_size = int (512 / size) else: @@ -573,17 +573,17 @@ def lookup_function (val): "Look-up and return a pretty-printer that can print val." # Get the type. - type = val.type (); + type = val.type; # If it points to a reference, get the reference. - if type.code () == gdb.TYPE_CODE_REF: + if type.code == gdb.TYPE_CODE_REF: type = type.target () # Get the unqualified type, stripped of typedefs. type = type.unqualified ().strip_typedefs () # Get the type name. - typename = type.tag () + typename = type.tag if typename == None: return None diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 4aae0aa..5e43267 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -83,6 +83,7 @@ PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args); PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args); PyObject *gdbpy_read_memory (PyObject *self, PyObject *args); PyObject *gdbpy_write_memory (PyObject *self, PyObject *args); +PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw); PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal); PyObject *symtab_to_symtab_object (struct symtab *symtab); diff --git a/gdb/python/python-type.c b/gdb/python/python-type.c index 2a54556..ec9ec46 100644 --- a/gdb/python/python-type.c +++ b/gdb/python/python-type.c @@ -103,6 +103,7 @@ field_dealloc (PyObject *obj) { field_object *f = (field_object *) obj; Py_XDECREF (f->dict); + f->ob_type->tp_free (obj); } static PyObject * @@ -125,7 +126,7 @@ field_new (void) /* Return the code for this type. */ static PyObject * -typy_code (PyObject *self, PyObject *args) +typy_get_code (PyObject *self, void *closure) { struct type *type = ((type_object *) self)->type; return PyInt_FromLong (TYPE_CODE (type)); @@ -232,7 +233,7 @@ typy_fields (PyObject *self, PyObject *args) /* Return the type's tag, or None. */ static PyObject * -typy_tag (PyObject *self, PyObject *args) +typy_get_tag (PyObject *self, void *closure) { struct type *type = ((type_object *) self)->type; if (!TYPE_TAG_NAME (type)) @@ -346,16 +347,16 @@ typy_unqualified (PyObject *self, PyObject *args) /* Return the size of the type represented by SELF, in bytes. */ static PyObject * -typy_sizeof (PyObject *self, PyObject *args) +typy_get_sizeof (PyObject *self, void *closure) { struct type *type = ((type_object *) self)->type; volatile struct gdb_exception except; TRY_CATCH (except, RETURN_MASK_ALL) { - CHECK_TYPEDEF (type); + check_typedef (type); } - GDB_PY_HANDLE_EXCEPTION (except); + /* Ignore exceptions. */ return PyLong_FromLong (TYPE_LENGTH (type)); } @@ -595,47 +596,6 @@ set_type (type_object *obj, struct type *type) obj->next = NULL; } -static PyObject * -typy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs) -{ - char *type_name = NULL; - struct type *type = NULL; - type_object *result; - PyObject *block_obj = NULL; - struct block *block = NULL; - - /* FIXME: it is strange to allow a Type with no name, but we need - this for type_to_type_object. */ - if (! PyArg_ParseTuple (args, "|sO", &type_name, &block_obj)) - return NULL; - - if (block_obj) - { - block = block_object_to_block (block_obj); - if (! block) - { - PyErr_SetString (PyExc_RuntimeError, - "second argument must be block"); - return NULL; - } - } - - if (type_name) - { - type = typy_lookup_typename (type_name, block); - if (! type) - return NULL; - } - - result = (type_object *) subtype->tp_alloc (subtype, 1); - if (! result) - return NULL; - - set_type (result, type); - - return (PyObject *) result; -} hooks/post-receive -- Repository for Project Archer.