mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
a9eac7f9b4
When running the gdb.base/index-cache.exp test case with the cc-with-dwz-m board, I noticed that the final executable didn't actually contain a .gnu_debugaltlink section with the name of the external dwz file: $ readelf --debug-dump=links testsuite/outputs/gdb.base/index-cache/index-cache * empty * Running dwz by hand, I realized it's because dwz complains that the output .debug_info section is empty and fails: $ gcc ~/src/binutils-gdb/gdb/testsuite/gdb.base/index-cache.c -g3 -O0 -o a && cp a b $ dwz -m foo a b dwz: foo: .debug_info section not present $ echo $? 1 This is because index-cache.c is trivial (just an empty main) and dwz doesn't find anything to factor out to the dwz file. [1] I think that cc-with-tweaks should fail in this scenario: if the user asks for an external dwz file to be generated (the -m flag), then it should be an error if cc-with-tweaks doesn't manage to produce an executable with the proper link to this external dwz file. Otherwise, the test runs with a regular non-dwzified executable, which gives a false sense of security about whether the feature under test works with dwzified executables. So this patch adds checks for that after invoking dwz. It also removes the 2>&1 to allow the error message to be printed like so: Running /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/index-cache.exp ... gdb compile failed, dwz: /home/smarchi/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/index-cache/index-cache.dwz: .debug_info section not present - In the -m case (multi-file compression), we check if the expected output file exists. - In the -z case (single-file compression), we check if the file contents has changed. This should catch cases where dwz doesn't modify the file because it's not worth it. It was chosen not to check for dwz's exit code, as it is not very reliable up to dwz 0.12. With this patch, fewer tests will pass than before with the cc-with-dwz and cc-with-dwz-m boards, but those were false positives anyway, as the test ran with regular executables. [1] Note that dwz has been patched by Tom de Vries to work correctly in this case, so we can use dwz master to run the test: https://sourceware.org/git/?p=dwz.git;a=commit;h=08becc8b33453b6d013a65e7eeae57fc1881e801 gdb/ChangeLog: * contrib/cc-with-tweaks.sh: Validate dwz's work.
234 lines
6.2 KiB
Bash
Executable File
234 lines
6.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Wrapper around gcc to tweak the output in various ways when running
|
|
# the testsuite.
|
|
|
|
# Copyright (C) 2010-2019 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/>.
|
|
|
|
# This program requires gdb and objcopy in addition to gcc.
|
|
# The default values are gdb from the build tree and objcopy from $PATH.
|
|
# They may be overridden by setting environment variables GDB and OBJCOPY
|
|
# respectively. Note that GDB should contain the gdb binary as well as the
|
|
# -data-directory flag, e.g., "foo/gdb -data-directory foo/data-directory".
|
|
# We assume the current directory is either $obj/gdb or $obj/gdb/testsuite.
|
|
#
|
|
# Example usage:
|
|
#
|
|
# bash$ cd $objdir/gdb/testsuite
|
|
# bash$ runtest \
|
|
# CC_FOR_TARGET="/bin/bash $srcdir/gdb/contrib/cc-with-tweaks.sh ARGS gcc" \
|
|
# CXX_FOR_TARGET="/bin/bash $srcdir/gdb/contrib/cc-with-tweaks.sh ARGS g++"
|
|
#
|
|
# For documentation on Fission and dwp files:
|
|
# http://gcc.gnu.org/wiki/DebugFission
|
|
# http://gcc.gnu.org/wiki/DebugFissionDWP
|
|
# For documentation on index files: info -f gdb.info -n "Index Files"
|
|
# For information about 'dwz', see the announcement:
|
|
# http://gcc.gnu.org/ml/gcc/2012-04/msg00686.html
|
|
# (More documentation is to come.)
|
|
|
|
# ARGS determine what is done. They can be:
|
|
# -Z invoke objcopy --compress-debug-sections
|
|
# -z compress using dwz
|
|
# -m compress using dwz -m
|
|
# -i make an index (.gdb_index)
|
|
# -n make a dwarf5 index (.debug_names)
|
|
# -p create .dwp files (Fission), you need to also use gcc option -gsplit-dwarf
|
|
# If nothing is given, no changes are made
|
|
|
|
myname=cc-with-tweaks.sh
|
|
mydir=`dirname "$0"`
|
|
|
|
if [ -z "$GDB" ]
|
|
then
|
|
if [ -f ./gdb ]
|
|
then
|
|
GDB="./gdb -data-directory data-directory"
|
|
elif [ -f ../gdb ]
|
|
then
|
|
GDB="../gdb -data-directory ../data-directory"
|
|
elif [ -f ../../gdb ]
|
|
then
|
|
GDB="../../gdb -data-directory ../../data-directory"
|
|
else
|
|
echo "$myname: unable to find usable gdb" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
OBJCOPY=${OBJCOPY:-objcopy}
|
|
READELF=${READELF:-readelf}
|
|
|
|
DWZ=${DWZ:-dwz}
|
|
DWP=${DWP:-dwp}
|
|
|
|
have_link=unknown
|
|
next_is_output_file=no
|
|
output_file=a.out
|
|
|
|
want_index=false
|
|
index_options=""
|
|
want_dwz=false
|
|
want_multi=false
|
|
want_dwp=false
|
|
want_objcopy_compress=false
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
-Z) want_objcopy_compress=true ;;
|
|
-z) want_dwz=true ;;
|
|
-i) want_index=true ;;
|
|
-n) want_index=true; index_options=-dwarf-5;;
|
|
-m) want_multi=true ;;
|
|
-p) want_dwp=true ;;
|
|
*) break ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ "$want_index" = true ]
|
|
then
|
|
if [ -z "$GDB_ADD_INDEX" ]
|
|
then
|
|
if [ -f $mydir/gdb-add-index.sh ]
|
|
then
|
|
GDB_ADD_INDEX="$mydir/gdb-add-index.sh"
|
|
else
|
|
echo "$myname: unable to find usable contrib/gdb-add-index.sh" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
for arg in "$@"
|
|
do
|
|
if [ "$next_is_output_file" = "yes" ]
|
|
then
|
|
output_file="$arg"
|
|
next_is_output_file=no
|
|
continue
|
|
fi
|
|
|
|
# Poor man's gcc argument parser.
|
|
# We don't need to handle all arguments, we just need to know if we're
|
|
# doing a link and what the output file is.
|
|
# It's not perfect, but it seems to work well enough for the task at hand.
|
|
case "$arg" in
|
|
"-c") have_link=no ;;
|
|
"-E") have_link=no ;;
|
|
"-S") have_link=no ;;
|
|
"-o") next_is_output_file=yes ;;
|
|
esac
|
|
done
|
|
|
|
if [ "$next_is_output_file" = "yes" ]
|
|
then
|
|
echo "$myname: Unable to find output file" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$have_link" = "no" ]
|
|
then
|
|
"$@"
|
|
exit $?
|
|
fi
|
|
|
|
index_file="${output_file}.gdb-index"
|
|
if [ "$want_index" = true ] && [ -f "$index_file" ]
|
|
then
|
|
echo "$myname: Index file $index_file exists, won't clobber." >&2
|
|
exit 1
|
|
fi
|
|
|
|
output_dir="${output_file%/*}"
|
|
[ "$output_dir" = "$output_file" ] && output_dir="."
|
|
|
|
"$@"
|
|
rc=$?
|
|
[ $rc != 0 ] && exit $rc
|
|
if [ ! -f "$output_file" ]
|
|
then
|
|
echo "$myname: Internal error: $output_file missing." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$want_objcopy_compress" = true ]; then
|
|
$OBJCOPY --compress-debug-sections "$output_file"
|
|
rc=$?
|
|
[ $rc != 0 ] && exit $rc
|
|
fi
|
|
|
|
if [ "$want_index" = true ]; then
|
|
# Filter out these messages which would stop dejagnu testcase run:
|
|
# echo "$myname: No index was created for $file" 1>&2
|
|
# echo "$myname: [Was there no debuginfo? Was there already an index?]" 1>&2
|
|
GDB=$GDB $GDB_ADD_INDEX $index_options "$output_file" 2>&1 \
|
|
| grep -v "^${GDB_ADD_INDEX##*/}: " >&2
|
|
rc=${PIPESTATUS[0]}
|
|
[ $rc != 0 ] && exit $rc
|
|
fi
|
|
|
|
if [ "$want_dwz" = true ]; then
|
|
# Validate dwz's result by checking if the executable was modified.
|
|
cp "$output_file" "${output_file}.copy"
|
|
$DWZ "$output_file" > /dev/null
|
|
cmp "$output_file" "$output_file.copy" > /dev/null
|
|
cmp_rc=$?
|
|
rm -f "${output_file}.copy"
|
|
|
|
case $cmp_rc in
|
|
0)
|
|
echo "$myname: dwz did not modify ${output_file}."
|
|
exit 1
|
|
;;
|
|
1)
|
|
# File was modified, great.
|
|
;;
|
|
*)
|
|
# Other cmp error, it presumably has already printed something on
|
|
# stderr.
|
|
exit 1
|
|
;;
|
|
esac
|
|
elif [ "$want_multi" = true ]; then
|
|
# Remove the dwz output file if it exists, so we don't mistake it for a
|
|
# new file in case dwz fails.
|
|
rm -f "${output_file}.dwz"
|
|
|
|
cp $output_file ${output_file}.alt
|
|
$DWZ -m ${output_file}.dwz "$output_file" ${output_file}.alt > /dev/null
|
|
rm -f ${output_file}.alt
|
|
|
|
# Validate dwz's work by checking if the expected output file exists.
|
|
if [ ! -f "${output_file}.dwz" ]; then
|
|
echo "$myname: dwz file ${output_file}.dwz missing."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ "$want_dwp" = true ]; then
|
|
dwo_files=$($READELF -wi "${output_file}" | grep _dwo_name | \
|
|
sed -e 's/^.*: //' | sort | uniq)
|
|
rc=0
|
|
if [ -n "$dwo_files" ]; then
|
|
$DWP -o "${output_file}.dwp" ${dwo_files} > /dev/null
|
|
rc=$?
|
|
[ $rc != 0 ] && exit $rc
|
|
rm -f ${dwo_files}
|
|
fi
|
|
fi
|
|
|
|
rm -f "$index_file"
|
|
exit $rc
|