dwarves/regtest
Arnaldo Carvalho de Melo fc1269af2f pahole: Introduce --classes_as_structs
That asks dwarf_fprintf to always use "struct" in places where it would
use "class", because CTF doesn't have the "class" concept, so for
'regtest diffctf' sake, we use this.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-08-24 17:22:43 -03:00

231 lines
6.7 KiB
Python
Executable File

#! /usr/bin/python
# -*- python -*-
# -*- coding: utf-8 -*-
# tuna - Application Tuning GUI
# Copyright (C) 2009 Arnaldo Carvalho de Melo
# Arnaldo Carvalho de Melo <acme@redhat.com>
#
# This application 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; version 2.
#
# This application 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.
import filecmp, os, posix, signal, sys, tempfile
regtest_output_dir = "/media/tb/pahole/regtest/"
regtest_obj_dir = "/media/tb/debuginfo/usr/lib/debug/"
tools = {"pahole": { "dwarf": "--flat_arrays --show_private_classes --fixup_silly_bitfields --first_obj_only --classes_as_structs" }}
formats = ("ctf", "dwarf")
len_debug_dir = len(regtest_obj_dir)
verbose = 1
def diff_file(from_filename, to_filename):
fd, diff_filename = tempfile.mkstemp()
command = 'diff -up "%s" "%s" > %s' % (from_filename,
to_filename, diff_filename)
if verbose > 1:
print command
try:
os.system(command)
os.system("vim %s" % diff_filename)
finally:
os.unlink(diff_filename)
def dir_has_no_diffs(dirname):
return os.access(os.path.join(dirname, ".no_diffs"), os.F_OK)
def set_dir_has_no_diffs(dirname):
f = file(os.path.join(dirname, ".no_diffs"), "w")
f.close()
def reset_dir_has_no_diffs(dirname):
os.unlink(os.path.join(dirname, ".no_diffs"))
def diff_dir(from_dir, to_dir, dir = None, recursive = True):
if dir:
from_dir = os.path.join(from_dir, dir)
to_dir = os.path.join(to_dir, dir)
print "\r%-130s" % from_dir
sys.stdout.flush()
diff = filecmp.dircmp(from_dir, to_dir)
if not dir_has_no_diffs(to_dir):
diff_files = diff.diff_files
if diff_files:
diff_files.sort()
print "\n %s" % from_dir
sys.stdout.flush()
for f in diff_files:
diff_file(os.path.join(from_dir, f),
os.path.join(to_dir, f))
else:
set_dir_has_no_diffs(to_dir)
if not recursive:
return
common_dirs = diff.common_dirs
if not common_dirs:
return
common_dirs.sort()
for dir in common_dirs:
diff_dir(from_dir, to_dir, dir)
def do_diff_dwarfs2ctfs():
diff_dir(os.path.join(regtest_output_dir, "after", "pahole", "dwarf"),
os.path.join(regtest_output_dir, "after", "pahole", "ctf"))
def do_diff_dwarfs():
diff_dir(os.path.join(regtest_output_dir, "before", "pahole", "dwarf"),
os.path.join(regtest_output_dir, "after", "pahole", "dwarf"))
def do_tool(tool, before_after, format, dirname, fname,
prepend_obj_dir = False):
if prepend_obj_dir:
fname += ".debug"
fixed_dirname = dirname
else:
fixed_dirname = dirname[len_debug_dir:]
tool_output_dir = os.path.join(regtest_output_dir,
before_after, tool, format,
fixed_dirname)
obj_path = os.path.join(dirname, fname)
if prepend_obj_dir:
obj_path = os.path.join(regtest_obj_dir, obj_path)
if os.path.islink(obj_path) or os.path.isdir(obj_path):
return
try:
os.makedirs(tool_output_dir)
except:
pass
if dir_has_no_diffs(tool_output_dir):
reset_dir_has_no_diffs(tool_output_dir)
output_file = os.path.join(tool_output_dir, fname[:-6])
if tools[tool].has_key(format):
options = tools[tool][format]
else:
options = ""
command = '%s -F %s %s %s > "%s"' % (tool, format, options,
obj_path, output_file)
if verbose > 1:
print command
sys.stdout.flush()
elif verbose > 0:
print "%s: %s" % (format,
os.path.join(fixed_dirname, fname[:-6]))
os.system(command)
def do_tool_on_files(arg, dirname, fnames, prepend_obj_dir = False):
if dirname.find("/.") >= 0:
return
tool, before_after = arg
for fname in fnames:
if not prepend_obj_dir and fname[-6:] != ".debug":
continue
for format in formats:
do_tool(tool, before_after, format, dirname, fname,
prepend_obj_dir)
def do_tools(before_after):
for tool in tools.keys():
os.path.walk(regtest_obj_dir, do_tool_on_files, (tool, before_after))
def do_ctf(dirname, fname, prepend_obj_dir = False):
if prepend_obj_dir:
fname += ".debug"
fixed_dirname = dirname
else:
fixed_dirname = dirname[len_debug_dir:]
obj_path = os.path.join(dirname, fname)
if prepend_obj_dir:
obj_path = os.path.join(regtest_obj_dir, obj_path)
if os.path.islink(obj_path) or os.path.isdir(obj_path):
return
command = 'pahole -Z "%s" 2> /dev/null' % obj_path
if verbose > 1:
print command
elif verbose > 0:
print os.path.join(fixed_dirname, fname[:-6])
os.system(command)
def do_ctf_on_files(arg, dirname, fnames, prepend_obj_dir = False):
if dirname.find("/.") >= 0:
return
for fname in fnames:
if not prepend_obj_dir and fname[-6:] != ".debug":
continue
do_ctf(dirname, fname, prepend_obj_dir)
def do_ctfs():
os.path.walk(regtest_obj_dir, do_ctf_on_files, None)
def sig_exit(sig_number, stack_frame):
sys.exit(1)
def listdebugs(dirname):
fnames = []
for fname in os.listdir(os.path.join(regtest_obj_dir, dirname)):
if fname[-6:] != ".debug":
continue
obj_path = os.path.join(regtest_obj_dir, dirname, fname)
if os.path.islink(obj_path) or os.path.isdir(obj_path):
continue
fnames.append(fname[:-6])
return fnames
def main(argv):
for sig in (signal.SIGHUP, signal.SIGINT, signal.SIGTERM):
signal.signal(sig, sig_exit)
try:
if len(argv) > 2:
dirname = argv[2]
if len(argv) > 3:
fnames = argv[3:]
elif argv[1] in ('before', 'after', 'ctf'):
fnames = listdebugs(dirname)
if argv[1] in ('before', 'after'):
if len(argv) > 2:
for tool in tools.keys():
arg = (tool, argv[1])
do_tool_on_files(arg, dirname, fnames, True)
else:
do_tools(argv[1])
elif argv[1] == 'diff':
if len(argv) > 2:
from_dir = os.path.join(regtest_output_dir, "before", "pahole", "dwarf", dirname)
to_dir = os.path.join(regtest_output_dir, "after", "pahole", "dwarf", dirname)
if len(argv) > 3:
for fname in fnames:
diff_file(os.path.join(from_dir, fname), os.path.join(to_dir, fname))
else:
diff_dir(from_dir, to_dir, recursive = False)
else:
do_diff_dwarfs()
elif argv[1] == 'ctf':
if len(argv) > 2:
do_ctf_on_files(None, dirname, fnames, True)
else:
do_ctfs()
elif argv[1] == 'diffctf':
if len(argv) > 2:
from_dir = os.path.join(regtest_output_dir, "after", "pahole", "dwarf", dirname)
to_dir = os.path.join(regtest_output_dir, "after", "pahole", "ctf", dirname)
if len(argv) > 3:
for fname in fnames:
diff_file(os.path.join(from_dir, fname), os.path.join(to_dir, fname))
else:
diff_dir(from_dir, to_dir, recursive = False)
else:
do_diff_dwarfs2ctfs()
except IOError:
pass
if __name__ == '__main__':
main(sys.argv)