diff --git a/test/difftree.sh b/test/difftree.sh new file mode 100755 index 0000000..08f90d9 --- /dev/null +++ b/test/difftree.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# The purpose of this test script is to determine if create-diff-object can +# properly recognize object file equivalence when passed the same file for both +# the original and patched objects. This verifies that create-diff-object is +# correctly parsing, correlating, and comparing the different elements of the +# object file. In practice, a situation similar to the test case occurs when a +# commonly included header file changes, causing Make to rebuild many objects +# that have no functional change. + +# This script requires a built kernel object tree to be in the kpatch cache +# directory at $HOME/.kpatch/obj + +#set -x + +OBJDIR="$HOME/.kpatch/obj" +SCRIPTDIR="$(readlink -f $(dirname $(type -p $0)))" +TEMPDIR=$(mktemp -d) +RESULTSDIR="$TEMPDIR/results" +VMVLINUX="/usr/lib/debug/lib/modules/$(uname -r)/vmlinux" # path for F20 + +if [[ ! -d $OBJDIR ]]; then + echo "please run kpatch-build to populate the object tree in $OBJDIR" +fi + +cd "$OBJDIR" || exit 1 +for i in $(find * -name '*.o') +do + # copied from kpatch-build/kpatch-gcc; keep in sync + case $i in + *.mod.o|\ + *built-in.o|\ + vmlinux.o|\ + .tmp_kallsyms1.o|\ + .tmp_kallsyms2.o|\ + init/version.o|\ + arch/x86/boot/version.o|\ + arch/x86/boot/compressed/eboot.o|\ + arch/x86/boot/header.o|\ + arch/x86/boot/compressed/efi_stub_64.o|\ + arch/x86/boot/compressed/piggy.o|\ + kernel/system_certificates.o|\ + .*.o) + continue + ;; + esac + # skip objects that are the linked product of more than one object file + [[ $(eu-readelf -s $i | grep FILE | wc -l) -ne 1 ]] && continue + $SCRIPTDIR/../kpatch-build/create-diff-object $i $i /usr/lib/debug/lib/modules/$(uname -r)/vmlinux "$TEMPDIR/output.o" > "$TEMPDIR/log.txt" 2>&1 + RETCODE=$? + # expect RETCODE to be 3 indicating no change + [[ $RETCODE -eq 3 ]] && continue + # otherwise record error + mkdir -p $RESULTSDIR/$(dirname $i) || exit 1 + cp "$i" "$RESULTSDIR/$i" || exit 1 + case $RETCODE in + 139) + echo "$i: segfault" | tee + if [[ ! -e core ]]; then + echo "no corefile, run "ulimit -c unlimited" to capture corefile" + else + mv core "$RESULTSDIR/$i.core" || exit 1 + fi + ;; + 0) + echo "$i: incorrectly detected change" + mv "$TEMPDIR/log.txt" "$RESULTSDIR/$i.log" || exit 1 + ;; + 1|2) + echo "$i: error code $RETCODE" + mv "$TEMPDIR/log.txt" "$RESULTSDIR/$i.log" || exit 1 + ;; + *) + exit 1 # script error + ;; + esac +done +rm -f "$TEMPDIR/log.txt" > /dev/null 2>&1 + +# try to group the errors together in some meaningful way +cd "$RESULTSDIR" || exit 1 +echo "" +echo "Results:" +for i in $(find * -iname '*.log') +do + echo $(cat $i | head -1 | cut -f2-3 -d':') +done | sort | uniq -c | sort -n -r | tee "$TEMPDIR/results.log" + +echo "results are in $TEMPDIR"