[PATCH 4/4] perf tests c2c: Add function view stdio coverage

From: Jiebin Sun

Date: Fri Aug 21 2026 - 01:49:55 EST


Exercise the function view without driving a terminal now that it has
a stdio path. Keep the existing datasym record/report coverage and make a
separate recording of the contended locks used by the futex hash benchmark.

Always check the function table headers, table replacement, missing-iaddr
diagnostic, and conflicting options. A machine can support c2c recording
without capturing a contended sample, so report a skip when the hierarchy
is empty rather than treating hardware sampling variance as a failure.

When samples are available, check generic row shapes for all three
hierarchy levels, their expanded fold signs, cacheline addresses, and the
absence of trailing whitespace in the table body.

Signed-off-by: Jiebin Sun <jiebin.sun@xxxxxxxxx>
Cc: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
Cc: Ian Rogers <irogers@xxxxxxxxxx>
Cc: James Clark <james.clark@xxxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
Cc: Thomas Falcon <thomas.falcon@xxxxxxxxx>
Reviewed-by: Tianyou Li <tianyou.li@xxxxxxxxx>
Reviewed-by: Wangyang Guo <wangyang.guo@xxxxxxxxx>
---
tools/perf/tests/shell/c2c.sh | 113 ++++++++++++++++++++++++++++++++++
1 file changed, 113 insertions(+)

diff --git a/tools/perf/tests/shell/c2c.sh b/tools/perf/tests/shell/c2c.sh
index f5f223cbf9cc..cf76359d19cc 100755
--- a/tools/perf/tests/shell/c2c.sh
+++ b/tools/perf/tests/shell/c2c.sh
@@ -6,10 +6,15 @@ set -e

err=0
perfdata=$(mktemp /tmp/__perf_c2c_test.perf.data.XXXXX)
+funcdata=$(mktemp /tmp/__perf_c2c_function_test.perf.data.XXXXX)
+perfout=$(mktemp /tmp/__perf_c2c_test.output.XXXXX)

cleanup() {
rm -f "${perfdata}"
rm -f "${perfdata}".old
+ rm -f "${funcdata}"
+ rm -f "${funcdata}".old
+ rm -f "${perfout}"
trap - EXIT TERM INT
}

@@ -58,6 +63,114 @@ test_c2c_record_report() {
echo "c2c record and report test [Success]"
}

+test_c2c_function_report() {
+ echo "c2c function stdio report test"
+
+ if perf c2c report -i "${perfdata}" --function -c pid > "${perfout}" 2>&1 ; then
+ echo "c2c function stdio report test [Failed: report accepted missing iaddr]"
+ err=1
+ return
+ fi
+ if ! grep -Fq "The function view requires iaddr in --coalesce." "${perfout}" ; then
+ echo "c2c function stdio report test [Failed: missing iaddr diagnostic]"
+ cat "${perfout}"
+ err=1
+ return
+ fi
+ if grep -Fq "Shared Data Functions Table" "${perfout}" ; then
+ echo "c2c function stdio report test [Failed: partial report on missing iaddr]"
+ cat "${perfout}"
+ err=1
+ return
+ fi
+
+ if perf c2c report -i "${perfdata}" --function --stats > "${perfout}" 2>&1 ; then
+ echo "c2c function stdio report test [Failed: accepted conflicting options]"
+ err=1
+ return
+ fi
+ if ! grep -Fq -- "--stats and --function cannot be used together." "${perfout}" ; then
+ echo "c2c function stdio report test [Failed: missing conflict diagnostic]"
+ cat "${perfout}"
+ err=1
+ return
+ fi
+
+ # Exercise contended futex hash-bucket locks so the function view can get
+ # reader, writer, and cacheline rows without changing the original test.
+ if ! perf c2c record -o "${funcdata}" -- \
+ perf bench futex hash -t 4 -r 1 -s > /dev/null 2>&1 ; then
+ echo "c2c function stdio report test [Skipped: recording failed]"
+ err=2
+ return
+ fi
+
+ if ! perf c2c report -i "${funcdata}" --function > "${perfout}" 2>&1 ; then
+ echo "c2c function stdio report test [Failed: report failed]"
+ cat "${perfout}"
+ err=1
+ return
+ fi
+
+ for expected in "Shared Data Functions Table" \
+ "# Cycles Store" \
+ "# % count Function / Contending function / Cacheline" \
+ "# ......... ......." ; do
+ if ! grep -Fq "${expected}" "${perfout}" ; then
+ echo "c2c function stdio report test [Failed: missing '${expected}']"
+ cat "${perfout}"
+ err=1
+ return
+ fi
+ done
+ for unexpected in "Shared Data Cache Line Table" \
+ "Shared Cache Line Distribution Pareto" ; do
+ if grep -Fq "${unexpected}" "${perfout}" ; then
+ echo "c2c function stdio report test [Failed: found '${unexpected}']"
+ cat "${perfout}"
+ err=1
+ return
+ fi
+ done
+
+ if ! awk '/^# \.+/ { body = 1; next }
+ body && !/^#/ && NF { found = 1 }
+ END { exit !found }' "${perfout}" ; then
+ echo "c2c function stdio report test [Skipped: no contended samples]"
+ err=2
+ return
+ fi
+
+ # The spaces intentionally verify per-level indentation and expanded
+ # fold-sign placement without depending on symbol names.
+ for expected in \
+ '^ - +[0-9]+\.[0-9]+% +[0-9]+ - ' \
+ '^ +[0-9]+ - ' \
+ '^ +[0-9]+ 0x[[:xdigit:]]+$' ; do
+ if ! grep -Eq "${expected}" "${perfout}" ; then
+ echo "c2c function stdio report test [Failed: missing hierarchy row]"
+ echo " ${expected}"
+ cat "${perfout}"
+ err=1
+ return
+ fi
+ done
+
+ if awk '/^# \.+/ { body = 1; next }
+ body && /[[:blank:]]$/ { found = 1 }
+ END { exit !found }' "${perfout}" ; then
+ echo "c2c function stdio report test [Failed: trailing whitespace in table body]"
+ cat "${perfout}"
+ err=1
+ return
+ fi
+
+ echo "c2c function stdio report test [Success]"
+}
+
test_c2c_record_report
+if [ "${err}" -eq 0 ]; then
+ test_c2c_function_report
+fi
cleanup
exit $err
--
2.52.0