2012-04-26 Sterling Augustine <saugustine@google.com>
* contrib: New directory. * contrib/test_pubnames_and_indexes.py: New file.
This commit is contained in:
parent
fceca5159f
commit
be36f02d8a
2 changed files with 212 additions and 0 deletions
|
@ -1,3 +1,8 @@
|
|||
2012-04-26 Sterling Augustine <saugustine@google.com>
|
||||
|
||||
* contrib: New directory.
|
||||
* contrib/test_pubnames_and_indexes.py: New file.
|
||||
|
||||
2012-04-30 Doug Evans <dje@google.com>
|
||||
|
||||
* dwarf2read.c (dwarf_decode_macros): New arg section_name.
|
||||
|
|
207
gdb/contrib/test_pubnames_and_indexes.py
Normal file
207
gdb/contrib/test_pubnames_and_indexes.py
Normal file
|
@ -0,0 +1,207 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
# Copyright (C) 2011-2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GDB.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
# This program requires readelf, gdb and objcopy. The default values are gdb
|
||||
# from the build tree and objcopy and readelf from $PATH. They may be
|
||||
# overridden by setting environment variables GDB, READELF and OBJCOPY
|
||||
# respectively. We assume the current directory is either $obj/gdb or
|
||||
# $obj/gdb/testsuite.
|
||||
#
|
||||
# Example usage:
|
||||
#
|
||||
# bash$ cd $objdir/gdb/testsuite
|
||||
# bash$ python test_pubnames_and_indexes.py <binary_name>
|
||||
|
||||
"""test_pubnames_and_indexes.py
|
||||
|
||||
Test that the gdb_index produced by gold is identical to the gdb_index
|
||||
produced by gdb itself.
|
||||
|
||||
Further check that the pubnames and pubtypes produced by gcc are identical
|
||||
to those that gdb produces.
|
||||
|
||||
Finally, check that all strings are canonicalized identically.
|
||||
"""
|
||||
|
||||
__author__ = 'saugustine@google.com (Sterling Augustine)'
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
OBJCOPY = None
|
||||
READELF = None
|
||||
GDB = None
|
||||
|
||||
def get_pub_info(filename, readelf_option):
|
||||
"""Parse and return all the pubnames or pubtypes produced by readelf with the
|
||||
given option.
|
||||
"""
|
||||
readelf = subprocess.Popen([READELF, '--debug-dump=' + readelf_option,
|
||||
filename], stdout=subprocess.PIPE)
|
||||
pubnames = []
|
||||
|
||||
in_list = False;
|
||||
for line in readelf.stdout:
|
||||
fields = line.split(None, 1)
|
||||
if (len(fields) == 2 and fields[0] == 'Offset'
|
||||
and fields[1].strip() == 'Name'):
|
||||
in_list = True
|
||||
# Either a blank-line or a new Length field terminates the current section.
|
||||
elif (len(fields) == 0 or fields[0] == 'Length:'):
|
||||
in_list = False;
|
||||
elif (in_list):
|
||||
pubnames.append(fields[1].strip())
|
||||
|
||||
readelf.wait()
|
||||
return pubnames
|
||||
|
||||
|
||||
def get_gdb_index(filename):
|
||||
"""Use readelf to dump the gdb index and collect the types and names"""
|
||||
readelf = subprocess.Popen([READELF, '--debug-dump=gdb_index',
|
||||
filename], stdout=subprocess.PIPE)
|
||||
index_symbols = []
|
||||
symbol_table_started = False
|
||||
for line in readelf.stdout:
|
||||
if (line == 'Symbol table:\n'):
|
||||
symbol_table_started = True;
|
||||
elif (symbol_table_started):
|
||||
# Readelf prints gdb-index lines formatted like so:
|
||||
# [ 4] two::c2<double>::c2: 0
|
||||
# So take the string between the first close bracket and the last colon.
|
||||
index_symbols.append(line[line.find(']') + 2: line.rfind(':')])
|
||||
|
||||
readelf.wait()
|
||||
return index_symbols
|
||||
|
||||
|
||||
def CheckSets(list0, list1, name0, name1):
|
||||
"""Report any setwise differences between the two lists"""
|
||||
|
||||
if len(list0) == 0 or len(list1) == 0:
|
||||
return False
|
||||
|
||||
difference0 = set(list0) - set(list1)
|
||||
if len(difference0) != 0:
|
||||
print "Elements in " + name0 + " but not " + name1 + ": (",
|
||||
print len(difference0),
|
||||
print ")"
|
||||
for element in difference0:
|
||||
print " " + element
|
||||
|
||||
difference1 = set(list1) - set(list0)
|
||||
if len(difference1) != 0:
|
||||
print "Elements in " + name1 + " but not " + name0 + ": (",
|
||||
print len(difference1),
|
||||
print ")"
|
||||
for element in difference1:
|
||||
print " " + element
|
||||
|
||||
if (len(difference0) != 0 or len(difference1) != 0):
|
||||
return True
|
||||
|
||||
print name0 + " and " + name1 + " are identical."
|
||||
return False
|
||||
|
||||
|
||||
def find_executables():
|
||||
"""Find the copies of readelf, objcopy and gdb to use."""
|
||||
# Executable finding logic follows cc-with-index.sh
|
||||
global READELF
|
||||
READELF = os.getenv('READELF')
|
||||
if READELF is None:
|
||||
READELF = 'readelf'
|
||||
global OBJCOPY
|
||||
OBJCOPY = os.getenv('OBJCOPY')
|
||||
if OBJCOPY is None:
|
||||
OBJCOPY = 'objcopy'
|
||||
|
||||
global GDB
|
||||
GDB = os.getenv('GDB')
|
||||
if (GDB is None):
|
||||
if os.path.isfile('./gdb') and os.access('./gdb', os.X_OK):
|
||||
GDB = './gdb'
|
||||
elif os.path.isfile('../gdb') and os.access('../gdb', os.X_OK):
|
||||
GDB = '../gdb'
|
||||
elif os.path.isfile('../../gdb') and os.access('../../gdb', os.X_OK):
|
||||
GDB = '../../gdb'
|
||||
else:
|
||||
# Punt and use the gdb in the path.
|
||||
GDB = 'gdb'
|
||||
|
||||
|
||||
def main(argv):
|
||||
"""The main subprogram."""
|
||||
if len(argv) != 2:
|
||||
print "Usage: test_pubnames_and_indexes.py <filename>"
|
||||
sys.exit(2)
|
||||
|
||||
find_executables();
|
||||
|
||||
# Get the index produced by Gold--It should have been built into the binary.
|
||||
gold_index = get_gdb_index(argv[1])
|
||||
|
||||
# Collect the pubnames and types list
|
||||
pubs_list = get_pub_info(argv[1], "pubnames")
|
||||
pubs_list = pubs_list + get_pub_info(argv[1], "pubtypes")
|
||||
|
||||
# Generate a .gdb_index with gdb
|
||||
gdb_index_file = argv[1] + '.gdb-generated-index'
|
||||
subprocess.check_call([OBJCOPY, '--remove-section', '.gdb_index',
|
||||
argv[1], gdb_index_file])
|
||||
subprocess.check_call([GDB, '-batch', '-nx', gdb_index_file,
|
||||
'-ex', 'save gdb-index ' + os.path.dirname(argv[1]),
|
||||
'-ex', 'quit'])
|
||||
subprocess.check_call([OBJCOPY, '--add-section',
|
||||
'.gdb_index=' + gdb_index_file + '.gdb-index',
|
||||
gdb_index_file])
|
||||
gdb_index = get_gdb_index(gdb_index_file)
|
||||
os.remove(gdb_index_file)
|
||||
os.remove(gdb_index_file + '.gdb-index')
|
||||
|
||||
failed = False
|
||||
gdb_index.sort()
|
||||
gold_index.sort()
|
||||
pubs_list.sort()
|
||||
|
||||
# Find the differences between the various indices.
|
||||
if len(gold_index) == 0:
|
||||
print "Gold index is empty"
|
||||
failed |= True
|
||||
|
||||
if len(gdb_index) == 0:
|
||||
print "Gdb index is empty"
|
||||
failed |= True
|
||||
|
||||
if len(pubs_list) == 0:
|
||||
print "Pubs list is empty"
|
||||
failed |= True
|
||||
|
||||
failed |= CheckSets(gdb_index, gold_index, "gdb index", "gold index")
|
||||
failed |= CheckSets(pubs_list, gold_index, "pubs list", "gold index")
|
||||
failed |= CheckSets(pubs_list, gdb_index, "pubs list", "gdb index")
|
||||
|
||||
if failed:
|
||||
print "Test failed"
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
Loading…
Reference in a new issue