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