[PATCH v3 06/13] perf tests: Fix Python JIT dump profiling test failure

From: Ian Rogers

Date: Tue Jun 16 2026 - 13:02:45 EST


The `python profiling with jitdump` test failed due to:
1. Target PID extraction resolving to duplicate space-separated values,
which broke the buildid-cache loops.
2. The default workload duration being too short to capture JIT stack
trampoline samples, resulting in 0 matching JIT symbols.

Fix the PID parsing by sorting and retrieving a unique single-line value.
Implement a robust retry loop starting at 1M python loop iterations and
scaling up to 100M iterations until JIT symbols are successfully captured
and verified.

Fixes: c9cd0c7e529e ("perf test: Add python JIT dump test")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
tools/perf/tests/shell/jitdump-python.sh | 79 ++++++++++++++++--------
1 file changed, 53 insertions(+), 26 deletions(-)

diff --git a/tools/perf/tests/shell/jitdump-python.sh b/tools/perf/tests/shell/jitdump-python.sh
index ae86203b14a2..05aaa3bd900b 100755
--- a/tools/perf/tests/shell/jitdump-python.sh
+++ b/tools/perf/tests/shell/jitdump-python.sh
@@ -16,11 +16,15 @@ if [ "${HAS_PERF_JIT}" != "True" ]; then
exit 2
fi

-PERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXXX)
+PERF_DATA_DIR=$(mktemp -d /tmp/__perf_test.perf.data.dir.XXXXXX)
+PERF_DATA="${PERF_DATA_DIR}/perf.data"

cleanup() {
echo "Cleaning up files..."
- rm -f ${PERF_DATA} ${PERF_DATA}.jit /tmp/jit-${PID}.dump /tmp/jitted-${PID}-*.so 2> /dev/null
+ rm -rf ${PERF_DATA_DIR} 2> /dev/null
+ for p in ${ALL_PIDS}; do
+ rm -f /tmp/jit-${p}.dump /tmp/jitted-${p}-*.so 2> /dev/null
+ done

trap - EXIT TERM INT
}
@@ -33,9 +37,16 @@ trap_cleanup() {

trap trap_cleanup EXIT TERM INT

-echo "Run python with -Xperf_jit"
-cat <<EOF | perf record -k 1 -g --call-graph dwarf -o "${PERF_DATA}" \
- -- ${PYTHON} -Xperf_jit
+ALL_PIDS=""
+NUM=0
+for iterations in 1000000 10000000 50000000 100000000; do
+ echo "Running with $iterations iterations..."
+ rm -f "${PERF_DATA}.pid"
+ cat <<EOF | perf record -k 1 -g --call-graph dwarf -o "${PERF_DATA}" -- ${PYTHON} -Xperf_jit
+import os
+with open("${PERF_DATA}.pid", "w") as f:
+ f.write(str(os.getpid()))
+
def foo(n):
result = 0
for _ in range(n):
@@ -49,29 +60,45 @@ def baz(n):
bar(n)

if __name__ == "__main__":
- baz(1000000)
+ baz($iterations)
EOF

-# extract PID of the target process from the data
-_PID=$(perf report -i "${PERF_DATA}" -F pid -q -g none | cut -d: -f1 -s)
-PID=$(echo -n $_PID) # remove newlines
-
-echo "Generate JIT-ed DSOs using perf inject"
-DEBUGINFOD_URLS='' perf inject -i "${PERF_DATA}" -j -o "${PERF_DATA}.jit"
-
-echo "Add JIT-ed DSOs to the build-ID cache"
-for F in /tmp/jitted-${PID}-*.so; do
- perf buildid-cache -a "${F}"
-done
-
-echo "Check the symbol containing the function/module name"
-NUM=$(perf report -i "${PERF_DATA}.jit" -s sym | grep -cE 'py::(foo|bar|baz):<stdin>')
-
-echo "Found ${NUM} matching lines"
-
-echo "Remove JIT-ed DSOs from the build-ID cache"
-for F in /tmp/jitted-${PID}-*.so; do
- perf buildid-cache -r "${F}"
+ if [ -f "${PERF_DATA}.pid" ]; then
+ REAL_PID=$(cat "${PERF_DATA}.pid")
+ ALL_PIDS="${ALL_PIDS} ${REAL_PID}"
+ fi
+
+ # extract PID of the target process from the data
+ PID=$(perf report -i "${PERF_DATA}" --stdio -F pid -q -g none | \
+ cut -d: -f1 -s | sort -u | head -n 1 | tr -d ' ')
+ if [ -z "${PID}" ]; then
+ echo "Failed to get PID, retrying..."
+ continue
+ fi
+ ALL_PIDS="${ALL_PIDS} ${PID}"
+
+ echo "Generate JIT-ed DSOs using perf inject"
+ DEBUGINFOD_URLS='' perf inject -i "${PERF_DATA}" -j -o "${PERF_DATA}.jit"
+
+ echo "Add JIT-ed DSOs to the build-ID cache"
+ for F in /tmp/jitted-${PID}-*.so; do
+ perf buildid-cache -a "${F}"
+ done
+
+ echo "Check the symbol containing the function/module name"
+ NUM=$(perf report -i "${PERF_DATA}.jit" -s sym --stdio | grep -cE 'py::(foo|bar|baz):<stdin>')
+
+ echo "Remove JIT-ed DSOs from the build-ID cache"
+ for F in /tmp/jitted-${PID}-*.so; do
+ perf buildid-cache -r "${F}"
+ done
+ rm -f /tmp/jitted-${PID}-*.so /tmp/jit-${PID}.dump 2>/dev/null
+
+ if [ "${NUM}" -gt 0 ]; then
+ echo "Success: found ${NUM} matching lines"
+ break
+ fi
+ echo "No matching lines found, retrying with more iterations..."
done

cleanup
--
2.54.0.1189.g8c84645362-goog