[tip: objtool/core] objtool/klp: Give each run one working directory, one per test inside it
From: tip-bot2 for Song Liu
Date: Fri Sep 18 2026 - 06:57:27 EST
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 00de45f4de3f39e191a7a81be2f38f7e325535ab
Gitweb: https://git.kernel.org/tip/00de45f4de3f39e191a7a81be2f38f7e325535ab
Author: Song Liu <song@xxxxxxxxxx>
AuthorDate: Wed, 16 Sep 2026 11:43:00 -07:00
Committer: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
CommitterDate: Wed, 16 Sep 2026 17:13:26 -07:00
objtool/klp: Give each run one working directory, one per test inside it
Each test made its own mktemp directory, so a run scattered them through
/tmp among everything else using the same names, and there was no way to
inspect what a failing test built -- the objects are gone the moment it
exits, which is right every time but the one that matters.
Give the run one directory and each test a subdirectory of it, named for
the test and nested the way the source is:
/tmp/klp-tests.3zC6oyfd/
generic/test-basic/{orig.o,patched.o,out.o,Module.symvers,...}
x86/test-kcfi/...
--keep then reports one path instead of forty, and removing it is one
command. A test run by hand still falls back to a temp directory of its
own, and still says where that went.
Detecting a leak comes free. Cleanup is now "remove each test's directory,
then rmdir the run's", and the rmdir fails if anything is left -- so a test
which dies without running its own cleanup is reported rather than quietly
leaving something behind.
preflight names the directory the tests build under, since mktemp honours
TMPDIR and a run in a container is otherwise silent about where its work
went. The runner says what to do only when it is relevant: on a failure
without --keep, that the option exists; with it, how many directories are
waiting. Usage text is not read while something is broken.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Song Liu <song@xxxxxxxxxx>
Link: https://patch.msgid.link/20260916184351.2720310-8-song@xxxxxxxxxx
Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
---
tools/objtool/tests/lib.sh | 23 ++++++++++++++++++-----
tools/objtool/tests/run-tests.sh | 26 ++++++++++++++++++++++++--
2 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/tools/objtool/tests/lib.sh b/tools/objtool/tests/lib.sh
index 817915e..82e6b0d 100644
--- a/tools/objtool/tests/lib.sh
+++ b/tools/objtool/tests/lib.sh
@@ -126,6 +126,7 @@ klp_preflight()
# objtool $OBJTOOL (klp: yes)
# compiler $cc_version
# arch $KLP_TEST_ARCH$([ "$arch" = "$host" ] || echo " (host $host, cross)")
+# tmpdir ${TMPDIR:-/tmp} (each test builds in a fresh directory here)
EOF
}
@@ -194,15 +195,27 @@ xpass()
exit 1
}
-cleanup() { [ -n "$workdir" ] && rm -rf "$workdir"; }
+cleanup()
+{
+ [ -n "$workdir" ] || return 0
+
+ if [ -n "${KLP_TEST_KEEP:-}" ]; then
+ [ -n "${KLP_TEST_WORKDIR:-}" ] || echo "# kept $workdir"
+ return 0
+ fi
+
+ rm -rf "$workdir"
+}
# setup [exported symbol...]
setup()
{
- # The environment was checked once when this file was sourced, so there
- # is nothing to verify here: objtool exists at the resolved path, has
- # klp support, and $CC works.
- workdir="$(mktemp -d)" || fail "mktemp failed"
+ if [ -n "${KLP_TEST_WORKDIR:-}" ]; then
+ workdir="$KLP_TEST_WORKDIR"
+ mkdir -p "$workdir" || fail "cannot create $workdir"
+ else
+ workdir="$(mktemp -d)" || fail "mktemp failed"
+ fi
trap cleanup EXIT
export_syms "$@"
diff --git a/tools/objtool/tests/run-tests.sh b/tools/objtool/tests/run-tests.sh
index 6b937fc..e6f1ac1 100755
--- a/tools/objtool/tests/run-tests.sh
+++ b/tools/objtool/tests/run-tests.sh
@@ -23,13 +23,17 @@ export LC_ALL=C
usage()
{
cat <<EOF
-usage: $(basename "$0") [test...]
+usage: $(basename "$0") [-k|--keep] [test...]
Run the objtool klp tests for this architecture: everything in generic/, plus
everything in the directory named for it. With no arguments, runs all of them.
A test may be named with or without its "test-" prefix and ".sh" suffix, and is
looked for in both directories.
+Options:
+ -k, --keep do not delete each test's working directory; print its path,
+ so the objects a failing test built can be looked at
+
Environment:
OBJTOOL objtool binary to test (default ../objtool)
CC compiler used to build fixtures (default gcc)
@@ -45,6 +49,7 @@ cd "$(dirname "$0")" || exit 1
while [ $# -gt 0 ]; do
case "$1" in
-h|--help) usage ;;
+ -k|--keep) export KLP_TEST_KEEP=1; shift ;;
--) shift; break ;;
-*) echo "unknown option: $1" >&2; usage 1 ;;
*) break ;;
@@ -98,12 +103,18 @@ else
done
fi
+# One directory for the whole run, one per test inside it, mirroring the
+# source layout. A run then leaves a single thing behind instead of 39
+# scattered among everything else using mktemp.
+rundir="$(mktemp -d "${TMPDIR:-/tmp}/klp-tests.XXXXXXXX")" ||
+ { echo "Bail out! cannot create a working directory" >&2; exit 1; }
+
echo "1..${#tests[@]}"
pass=0 fail=0 static_skip=0 probe_skip=0 xfail=0 xpass=0
for t in "${tests[@]}"; do
- out="$(./"$t" 2>&1)"
+ out="$(KLP_TEST_WORKDIR="$rundir/${t%.sh}" ./"$t" 2>&1)"
rc=$?
# A test prints one result line, but it is not necessarily the only
@@ -156,4 +167,15 @@ done
echo "# pass:$pass fail:$fail static-skip:$static_skip" \
"probe-skip:$probe_skip xfail:$xfail xpass:$xpass"
+# A failure is the one time the objects matter, and by default they are
+# already gone. Say so then rather than in the usage text nobody reads while
+# something is broken.
+if [ -n "${KLP_TEST_KEEP:-}" ]; then
+ echo "# working directories kept in $rundir -- inspect, then rm -rf it"
+elif ! rmdir "$rundir"/*/ "$rundir" 2>/dev/null; then
+ echo "# $rundir was not empty; a test did not clean up after itself"
+elif [ "$fail" != 0 ] || [ "$xpass" != 0 ]; then
+ echo "# re-run with --keep to hold on to what a failing test built"
+fi
+
[ "$fail" = 0 ] && [ "$xpass" = 0 ]