| #!/bin/sh |
| # SPDX-License-Identifier: GPL-2.0 |
| # Test libdw unwinding of multi-threaded processes (exclusive) |
| |
| set -e |
| |
| if ! perf check feature -q libdw-dwarf-unwind; then |
| echo "Skip: libdw DWARF unwinding is not available" |
| exit 2 |
| fi |
| |
| tmpdir=$(mktemp -d /tmp/perf-test-dwarf-unwind-multithreaded.XXXXXX) |
| perf_data="$tmpdir/perf.data" |
| perf_script="$tmpdir/perf-script.txt" |
| nr_threads=4 |
| nr_worker_threads=$((nr_threads - 1)) |
| |
| cleanup() |
| { |
| trap - EXIT TERM INT |
| rm -rf "$tmpdir" |
| } |
| |
| trap cleanup EXIT TERM INT |
| |
| if ! perf record -q -e task-clock:u -F 99 --call-graph dwarf,8192 \ |
| -o "$perf_data" -- perf test -w thloop 2 "$nr_threads" |
| then |
| echo "Skip: failed to record task-clock:u" |
| exit 2 |
| fi |
| |
| if ! perf script --unwind-style=libdw \ |
| -F comm,pid,tid,event,ip,sym -i "$perf_data" > "$perf_script" |
| then |
| echo "Error: failed to process the recording with libdw" >&2 |
| exit 1 |
| fi |
| |
| nr_unwound_threads=$( |
| awk ' |
| BEGIN { RS = "" } |
| |
| # thfunc is the worker-only caller of test_loop. Finding it proves |
| # that libdw unwound beyond the sampled leaf for this worker TID. |
| /thfunc/ { |
| split($2, id, "/") |
| seen[id[2]] = 1 |
| } |
| |
| END { |
| for (tid in seen) |
| nr_tids++ |
| print nr_tids + 0 |
| } |
| ' "$perf_script" |
| ) |
| |
| if [ "$nr_unwound_threads" -ne "$nr_worker_threads" ]; then |
| echo "Error: expected callchains for $nr_worker_threads worker TIDs," \ |
| "found $nr_unwound_threads" >&2 |
| exit 1 |
| fi |
| |
| exit 0 |