f194210846
The perf test named “build id cache operations” skips with below error on some distros: <<>> 78: build id cache operations : test child forked, pid 111101 WARNING: wine not found. PE binaries will not be run. test binaries: /tmp/perf.ex.SHA1.PKz /tmp/perf.ex.MD5.Gt3 ./tests/shell/../pe-file.exe DEBUGINFOD_URLS= Adding 4abd406f041feb4f10ecde3fc30fd0639e1a91cb /tmp/perf.ex.SHA1.PKz: Ok build id: 4abd406f041feb4f10ecde3fc30fd0639e1a91cb ./tests/shell/buildid.sh: 69: ./tests/shell/buildid.sh: Bad substitution test child finished with -2 build id cache operations: Skip <<>> The test script "tests/shell/buildid.sh" uses some of the string substitution ways which are supported in bash, but not in "sh" or other shells. Above error on line number 69 that reports "Bad substitution" is: <<>> link=${build_id_dir}/.build-id/${id:0:2}/${id:2} <<>> Here the way of getting first two characters from id ie, ${id:0:2} and similarly expressions like ${id:2} is not recognised in "sh". So the line errors and instead of hitting failure, the test gets skipped as shown in logs. So the syntax issue causes test not to be executed in such cases. Similarly usage : "${@: -1}" [ to pick last argument passed to a function] in “test_record” doesn’t work in all distros. Fix this by using alternative way with shell substitution to pick required characters from the string. Also fix the usage of “${@: -1}” to work in all cases. Another usage in “test_record” is: <<>> ${perf} record --buildid-all -o ${data} $@ &> ${log} <<>> This causes the 'perf record' to start in background and Results in the data file not being created by the time "check" function is invoked. Below log shows 'perf record' result getting displayed after the call to "check" function. <<>> running: perf record /tmp/perf.ex.SHA1.EAU build id: 4abd406f041feb4f10ecde3fc30fd0639e1a91cb link: /tmp/perf.debug.mLT/.build-id/4a/bd406f041feb4f10ecde3fc30fd0639e1a91cb failed: link /tmp/perf.debug.mLT/.build-id/4a/bd406f041feb4f10ecde3fc30fd0639e1a91cb does not exist test child finished with -1 build id cache operations: FAILED! root@machine:~/athira/linux/tools/perf# Couldn't synthesize bpf events. [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.010 MB /tmp/perf.data.bFF ] <<>> Fix this by redirecting output instead of using “&” which starts the command in background. Reviewed-by: David Laight <David.Laight@ACULAB.COM> Signed-off-by: Athira Jajeev <atrajeev@linux.vnet.ibm.com> Tested-by: Disha Goel <disgoel@linux.ibm.com> Acked-by: Ian Rogers <irogers@google.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: James Clark <james.clark@arm.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nageswara R Sastry <rnsastry@linux.ibm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230119142719.32628-1-atrajeev@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
176 lines
4.1 KiB
Bash
Executable File
176 lines
4.1 KiB
Bash
Executable File
#!/bin/sh
|
|
# build id cache operations
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
# skip if there's no readelf
|
|
if ! [ -x "$(command -v readelf)" ]; then
|
|
echo "failed: no readelf, install binutils"
|
|
exit 2
|
|
fi
|
|
|
|
# skip if there's no compiler
|
|
if ! [ -x "$(command -v cc)" ]; then
|
|
echo "failed: no compiler, install gcc"
|
|
exit 2
|
|
fi
|
|
|
|
# check what we need to test windows binaries
|
|
add_pe=1
|
|
run_pe=1
|
|
if ! perf version --build-options | grep -q 'libbfd: .* on '; then
|
|
echo "WARNING: perf not built with libbfd. PE binaries will not be tested."
|
|
add_pe=0
|
|
run_pe=0
|
|
fi
|
|
if ! which wine > /dev/null; then
|
|
echo "WARNING: wine not found. PE binaries will not be run."
|
|
run_pe=0
|
|
fi
|
|
|
|
# set up wine
|
|
if [ ${run_pe} -eq 1 ]; then
|
|
wineprefix=$(mktemp -d /tmp/perf.wineprefix.XXX)
|
|
export WINEPREFIX=${wineprefix}
|
|
# clear display variables to prevent wine from popping up dialogs
|
|
unset DISPLAY
|
|
unset WAYLAND_DISPLAY
|
|
fi
|
|
|
|
ex_md5=$(mktemp /tmp/perf.ex.MD5.XXX)
|
|
ex_sha1=$(mktemp /tmp/perf.ex.SHA1.XXX)
|
|
ex_pe=$(dirname $0)/../pe-file.exe
|
|
|
|
echo 'int main(void) { return 0; }' | cc -Wl,--build-id=sha1 -o ${ex_sha1} -x c -
|
|
echo 'int main(void) { return 0; }' | cc -Wl,--build-id=md5 -o ${ex_md5} -x c -
|
|
|
|
echo "test binaries: ${ex_sha1} ${ex_md5} ${ex_pe}"
|
|
|
|
check()
|
|
{
|
|
case $1 in
|
|
*.exe)
|
|
# We don't have a tool that can pull a nicely formatted build-id out of
|
|
# a PE file, but we can extract the whole section with objcopy and
|
|
# format it ourselves. The .buildid section is a Debug Directory
|
|
# containing a CodeView entry:
|
|
# https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#debug-directory-image-only
|
|
# https://github.com/dotnet/runtime/blob/da94c022576a5c3bbc0e896f006565905eb137f9/docs/design/specs/PE-COFF.md
|
|
# The build-id starts at byte 33 and must be rearranged into a GUID.
|
|
id=`objcopy -O binary --only-section=.buildid $1 /dev/stdout | \
|
|
cut -c 33-48 | hexdump -ve '/1 "%02x"' | \
|
|
sed 's@^\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(.*\)0a$@\4\3\2\1\6\5\8\7\9@'`
|
|
;;
|
|
*)
|
|
id=`readelf -n ${1} 2>/dev/null | grep 'Build ID' | awk '{print $3}'`
|
|
;;
|
|
esac
|
|
echo "build id: ${id}"
|
|
|
|
id_file=${id#??}
|
|
id_dir=${id%$id_file}
|
|
link=$build_id_dir/.build-id/$id_dir/$id_file
|
|
echo "link: ${link}"
|
|
|
|
if [ ! -h $link ]; then
|
|
echo "failed: link ${link} does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
file=${build_id_dir}/.build-id/$id_dir/`readlink ${link}`/elf
|
|
echo "file: ${file}"
|
|
|
|
# Check for file permission of original file
|
|
# in case of pe-file.exe file
|
|
echo $1 | grep ".exe"
|
|
if [ $? -eq 0 ]; then
|
|
if [ -x $1 -a ! -x $file ]; then
|
|
echo "failed: file ${file} executable does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -x $file -a ! -e $file ]; then
|
|
echo "failed: file ${file} does not exist"
|
|
exit 1
|
|
fi
|
|
elif [ ! -x $file ]; then
|
|
echo "failed: file ${file} does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
diff ${file} ${1}
|
|
if [ $? -ne 0 ]; then
|
|
echo "failed: ${file} do not match"
|
|
exit 1
|
|
fi
|
|
|
|
${perf} buildid-cache -l | grep ${id}
|
|
if [ $? -ne 0 ]; then
|
|
echo "failed: ${id} is not reported by \"perf buildid-cache -l\""
|
|
exit 1
|
|
fi
|
|
|
|
echo "OK for ${1}"
|
|
}
|
|
|
|
test_add()
|
|
{
|
|
build_id_dir=$(mktemp -d /tmp/perf.debug.XXX)
|
|
perf="perf --buildid-dir ${build_id_dir}"
|
|
|
|
${perf} buildid-cache -v -a ${1}
|
|
if [ $? -ne 0 ]; then
|
|
echo "failed: add ${1} to build id cache"
|
|
exit 1
|
|
fi
|
|
|
|
check ${1}
|
|
|
|
rm -rf ${build_id_dir}
|
|
}
|
|
|
|
test_record()
|
|
{
|
|
data=$(mktemp /tmp/perf.data.XXX)
|
|
build_id_dir=$(mktemp -d /tmp/perf.debug.XXX)
|
|
log_out=$(mktemp /tmp/perf.log.out.XXX)
|
|
log_err=$(mktemp /tmp/perf.log.err.XXX)
|
|
perf="perf --buildid-dir ${build_id_dir}"
|
|
|
|
echo "running: perf record $@"
|
|
${perf} record --buildid-all -o ${data} $@ 1>${log_out} 2>${log_err}
|
|
if [ $? -ne 0 ]; then
|
|
echo "failed: record $@"
|
|
echo "see log: ${log_err}"
|
|
exit 1
|
|
fi
|
|
|
|
args="$*"
|
|
check ${args##* }
|
|
|
|
rm -f ${log_out} ${log_err}
|
|
rm -rf ${build_id_dir}
|
|
rm -rf ${data}
|
|
}
|
|
|
|
# add binaries manual via perf buildid-cache -a
|
|
test_add ${ex_sha1}
|
|
test_add ${ex_md5}
|
|
if [ ${add_pe} -eq 1 ]; then
|
|
test_add ${ex_pe}
|
|
fi
|
|
|
|
# add binaries via perf record post processing
|
|
test_record ${ex_sha1}
|
|
test_record ${ex_md5}
|
|
if [ ${run_pe} -eq 1 ]; then
|
|
test_record wine ${ex_pe}
|
|
fi
|
|
|
|
# cleanup
|
|
rm ${ex_sha1} ${ex_md5}
|
|
if [ ${run_pe} -eq 1 ]; then
|
|
rm -r ${wineprefix}
|
|
fi
|
|
|
|
exit ${err}
|