xref: /linux/tools/perf/tests/shell/test_dwarf_unwind_multithreaded.sh (revision 473f6c8f437b049f8ec015d57cd59bb983b1d85c)
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3# Test libdw unwinding of multi-threaded processes (exclusive)
4
5set -e
6
7if ! perf check feature -q libdw-dwarf-unwind; then
8	echo "Skip: libdw DWARF unwinding is not available"
9	exit 2
10fi
11
12tmpdir=$(mktemp -d /tmp/perf-test-dwarf-unwind-multithreaded.XXXXXX)
13perf_data="$tmpdir/perf.data"
14perf_script="$tmpdir/perf-script.txt"
15nr_threads=4
16nr_worker_threads=$((nr_threads - 1))
17
18cleanup()
19{
20	trap - EXIT TERM INT
21	rm -rf "$tmpdir"
22}
23
24trap cleanup EXIT TERM INT
25
26if ! perf record -q -e task-clock:u -F 99 --call-graph dwarf,8192 \
27	-o "$perf_data" -- perf test -w thloop 2 "$nr_threads"
28then
29	echo "Skip: failed to record task-clock:u"
30	exit 2
31fi
32
33if ! perf script --unwind-style=libdw \
34	-F comm,pid,tid,event,ip,sym -i "$perf_data" > "$perf_script"
35then
36	echo "Error: failed to process the recording with libdw" >&2
37	exit 1
38fi
39
40nr_unwound_threads=$(
41	awk '
42		BEGIN { RS = "" }
43
44		# thfunc is the worker-only caller of test_loop. Finding it proves
45		# that libdw unwound beyond the sampled leaf for this worker TID.
46		/thfunc/ {
47			split($2, id, "/")
48			seen[id[2]] = 1
49		}
50
51		END {
52			for (tid in seen)
53				nr_tids++
54			print nr_tids + 0
55		}
56	' "$perf_script"
57)
58
59if [ "$nr_unwound_threads" -ne "$nr_worker_threads" ]; then
60	echo "Error: expected callchains for $nr_worker_threads worker TIDs," \
61		"found $nr_unwound_threads" >&2
62	exit 1
63fi
64
65exit 0
66