projects/linux·blob master · refs

65 lines · 1.4 KiB

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