This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[python] one more new command


Here's the last new command that I had sitting around.  This is a
miniature (i.e., less functional) clone of the dwarves "pahole"
utility.  You can use this to find holes in structures so that they
can be packed more tightly.

This particular command can be useful for scripting.  Try:

    ./gdb ./gdb -batch -ex 'require command pahole' -ex 'pahole struct type'


FWIW the only other python code I have here is a test command to pull
up a Gtk window in a separate thread.  This is cute but not useful for
anything.

Tom

2008-11-24  Tom Tromey  <tromey@redhat.com>

	* Makefile.in (PY_FILES): Add new file.
	* python/lib/gdb/command/pahole.py: New file.

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 935748d..4251bdf 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1923,10 +1923,11 @@ python-value.o: $(srcdir)/python/python-value.c
 # Note that we should only install files in the "gdb" module.
 PY_FILES = gdb/FrameIterator.py gdb/command/alias.py \
     gdb/command/backtrace.py gdb/command/require.py \
-    gdb/command/__init__.py gdb/libstdcxx/v6/printers.py \
-    gdb/libstdcxx/v6/__init__.py gdb/libstdcxx/__init__.py \
-    gdb/function/caller_is.py gdb/function/in_scope.py \
-    gdb/function/__init__.py gdb/backtrace.py gdb/__init__.py
+    gdb/command/pahole.py gdb/command/__init__.py \
+    gdb/libstdcxx/v6/printers.py gdb/libstdcxx/v6/__init__.py \
+    gdb/libstdcxx/__init__.py gdb/function/caller_is.py	\
+    gdb/function/in_scope.py gdb/function/__init__.py gdb/backtrace.py \
+    gdb/__init__.py
 
 # Install the Python library.  Python library files go under
 # $(GDB_DATADIR_PATH)/python.
diff --git a/gdb/python/lib/gdb/command/pahole.py b/gdb/python/lib/gdb/command/pahole.py
new file mode 100644
index 0000000..b159937
--- /dev/null
+++ b/gdb/python/lib/gdb/command/pahole.py
@@ -0,0 +1,81 @@
+# pahole command for gdb
+
+# Copyright (C) 2008 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
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gdb
+
+class Pahole (gdb.Command):
+    """Show the holes in a structure.
+This command takes a single argument, a type name.
+It prints the type and displays comments showing where holes are."""
+
+    def __init__ (self):
+        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 ()
+        if tag is None:
+            tag = ''
+        print '%sstruct %s {' % (' ' * (2 * level), tag)
+        bitpos = 0
+        for field in type.fields ():
+            # Skip static fields.
+            if not hasattr (field, ('bitpos')):
+                continue
+
+            ftype = self.strip (field.type)
+
+            if bitpos != field.bitpos:
+                hole = field.bitpos - bitpos
+                print '  /* XXX %d bit hole, try to pack */' % hole
+                bitpos = field.bitpos
+            if field.bitsize > 0:
+                fieldsize = field.bitsize
+            else:
+                # TARGET_CHAR_BIT here...
+                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:
+                self.pahole (ftype, level + 1, field.name)
+            else:
+                print ' ' * (2 + 2 * level),
+                print '%s %s' % (str (ftype), field.name)
+
+        print ' ' * (14 + 2 * level),
+        print '} %s' % name
+
+    def invoke (self, arg, from_tty):
+        type = gdb.Type (arg)
+        type = self.strip (type)
+        if type.code () != gdb.TYPE_CODE_STRUCT:
+            raise '%s is not a struct type' % arg
+        print ' ' * 14,
+        self.pahole (type, 0, '')
+
+Pahole()


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]