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