From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23954 invoked by alias); 27 May 2010 00:09:15 -0000 Received: (qmail 23928 invoked by uid 22791); 27 May 2010 00:09:12 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 27 May 2010 00:09:05 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id AE3D72BAB97; Wed, 26 May 2010 20:09:03 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 3IuN6X4IZj0D; Wed, 26 May 2010 20:09:03 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 473E52BABF1; Wed, 26 May 2010 20:09:03 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id E72A4F58FA; Wed, 26 May 2010 17:08:51 -0700 (PDT) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Joel Brobecker Subject: [RFA/python:2/2] First script in GDB python library - command/pahole.py Date: Thu, 27 May 2010 00:09:00 -0000 Message-Id: <1274918921-23200-3-git-send-email-brobecker@adacore.com> In-Reply-To: <1274918921-23200-1-git-send-email-brobecker@adacore.com> References: <1274918921-23200-1-git-send-email-brobecker@adacore.com> 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: 2010-05/txt/msg00621.txt.bz2 This patch makes use of the work done in the previous patch that allows to store the GDB python library at a global location. It updates the Makefile.in, adding install-python and uninstall-python targets. And it also introduces the first script in the GDB python library: pahole.py. Pretty much 100% of the code comes from Archer, and I think that Tom is the original author of that code. I only tweaked it a little to make it work at the FSF level (there are some API differences between the Archer tree and the FSF tree). 2010-05-22 Tom Tromey Joel Brobecker * Makefile.in (GDB_PYTHONDIR, PY_FILES): New variabls. (install-python, uninstall-python): New rules. * python/lib/gdb/__init__.py, python/lib/gdb/command/__init__.py, python/lib/gdb/command/pahole.py: New files. Tested on x86_64-linux. --- gdb/Makefile.in | 32 +++++++++++++ gdb/python/lib/gdb/__init__.py | 16 ++++++ gdb/python/lib/gdb/command/__init__.py | 16 ++++++ gdb/python/lib/gdb/command/pahole.py | 81 ++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 0 deletions(-) create mode 100644 gdb/python/lib/gdb/__init__.py create mode 100644 gdb/python/lib/gdb/command/__init__.py create mode 100644 gdb/python/lib/gdb/command/pahole.py diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 754671f..e61ed4f 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -169,6 +169,9 @@ TARGET_SYSTEM_ROOT_DEFINE = @TARGET_SYSTEM_ROOT_DEFINE@ # Did the user give us a --with-gdb-datadir option? GDB_DATADIR = @GDB_DATADIR@ +# The location where the GDB python library is located. +GDB_PYTHONDIR = @GDB_PYTHONDIR@ + # Helper code from gnulib. LIBGNU = gnulib/libgnu.a INCGNU = -I$(srcdir)/gnulib -Ignulib @@ -2057,6 +2060,35 @@ py-value.o: $(srcdir)/python/py-value.c $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-value.c $(POSTCOMPILE) +# All python library files, with the "python/lib" stripped off. +# Note that we should only install files in the "gdb" module. +PY_FILES = gdb/command/pahole.py gdb/command/__init__.py \ + gdb/__init__.py + +# Install the Python library. Python library files go under +# $(GDB_PYTHONDIR). +.PHONY: install-python +install-python: + files='$(PY_FILES)'; for file in $$files; do \ + dir=`echo "$$file" | sed 's,/[^/]*$$,,'`; \ + $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_PYTHONDIR)/$$dir; \ + $(INSTALL_DATA) $(srcdir)/python/lib/$$file $(DESTDIR)$(GDB_PYTHONDIR)/$$file; \ + done + +# Other packages may have their files installed in $(GDB_PYTHONDIR). +.PHONY: uninstall-python +uninstall-python: + files='$(PY_FILES)'; for file in $$files; do \ + slashdir=`echo "/$$file" | sed 's,/[^/]*$$,,'`; \ + rm -f $(DESTDIR)$(GDB_PYTHONDIR)/$$file; \ + while test "x$$file" != "x$$slashdir"; do \ + rmdir 2>/dev/null "$(DESTDIR)$(GDB_PYTHONDIR)$$slashdir"; \ + file="$$slashdir"; \ + slashdir=`echo "$$file" | sed 's,/[^/]*$$,,'`; \ + done \ + done + + # # Dependency tracking. Most of this is conditional on GNU Make being # found by configure; if GNU Make is not found, we fall back to a diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py new file mode 100644 index 0000000..4263473 --- /dev/null +++ b/gdb/python/lib/gdb/__init__.py @@ -0,0 +1,16 @@ +# Copyright (C) 2010 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 . + + diff --git a/gdb/python/lib/gdb/command/__init__.py b/gdb/python/lib/gdb/command/__init__.py new file mode 100644 index 0000000..4263473 --- /dev/null +++ b/gdb/python/lib/gdb/command/__init__.py @@ -0,0 +1,16 @@ +# Copyright (C) 2010 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 . + + diff --git a/gdb/python/lib/gdb/command/pahole.py b/gdb/python/lib/gdb/command/pahole.py new file mode 100644 index 0000000..32e694d --- /dev/null +++ b/gdb/python/lib/gdb/command/pahole.py @@ -0,0 +1,81 @@ +# pahole command for gdb + +# Copyright (C) 2008, 2010 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 . + +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.lookup_type(arg) + type = self.strip(type) + if type.code != gdb.TYPE_CODE_STRUCT: + raise TypeError, '%s is not a struct type' % arg + print ' ' * 14, + self.pahole(type, 0, '') + +Pahole() -- 1.7.1