Files
chromebox_10th_audio_driver/scripts/sof-trace-capture.sh

173 lines
5.2 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
LOG_DIR="${REPO_ROOT}/_logs"
SOF_BIN_ROOT="${SOF_BIN_ROOT:-/var/tmp/sof-bin-upgrade/sof-bin-2025.12.2}"
SOF_LOGGER="${SOF_LOGGER:-${SOF_BIN_ROOT}/tools/sof-logger}"
SOF_LDC_DEFAULT="${SOF_LDC_DEFAULT:-${SOF_BIN_ROOT}/sof/sof-cml.ldc}"
mkdir -p "${LOG_DIR}"
ts="$(date +%Y%m%d_%H%M%S)"
start_ts_human="$(date '+%F %T')"
sof_log="${LOG_DIR}/sof-logger_${ts}.log"
kernel_log="${LOG_DIR}/kernel_sof_ipc_${ts}.log"
pipewire_log="${LOG_DIR}/user_pipewire_${ts}.log"
sof_debug_snapshot="${LOG_DIR}/sof-debugfs_${ts}.txt"
echo "[INFO] repo=${REPO_ROOT}"
echo "[INFO] log_dir=${LOG_DIR}"
echo "[INFO] start_ts=${start_ts_human}"
echo
if [[ "${EUID}" -ne 0 ]]; then
echo "[ERROR] 请用 sudo 运行sudo bash scripts/sof-trace-capture.sh" >&2
exit 1
fi
echo "[STEP] 1) 确保 debugfs 已挂载 (/sys/kernel/debug)"
if ! mountpoint -q /sys/kernel/debug; then
mount -t debugfs none /sys/kernel/debug
fi
if [[ ! -d /sys/kernel/debug ]]; then
echo "[ERROR] /sys/kernel/debug 不存在?" >&2
exit 1
fi
echo "[INFO] debugfs: OK"
echo
echo "[STEP] 2) 检查 sof-logger 工具"
if [[ ! -x "${SOF_LOGGER}" ]]; then
echo "[ERROR] 找不到可执行的 sof-logger" >&2
echo " ${SOF_LOGGER}" >&2
echo " 可通过环境变量覆盖SOF_BIN_ROOT 或 SOF_LOGGER" >&2
exit 1
fi
echo "[INFO] sof-logger=${SOF_LOGGER}"
echo
echo "[STEP] 2.1) 确认 SOF dictionary (.ldc)"
SOF_LDC="${SOF_LDC:-${SOF_LDC_DEFAULT}}"
if [[ ! -e "${SOF_LDC}" ]]; then
echo "[ERROR] 未找到 SOF .ldc 文件:" >&2
echo " ${SOF_LDC}" >&2
echo " 可通过环境变量覆盖SOF_LDC" >&2
exit 1
fi
echo "[INFO] SOF_LDC=${SOF_LDC}"
echo
echo "[STEP] 2.2) 确认 debugfs 下的 SOF trace 节点"
# We expect one of these to exist when SOF is running.
SOF_TRACE_NODE=""
SOF_TRACE_MODE=""
for p in /sys/kernel/debug/sof/trace /sys/kernel/debug/sof/etrace; do
if [[ -e "$p" ]]; then
SOF_TRACE_NODE="$p"
if [[ "$p" == */trace ]]; then
SOF_TRACE_MODE="trace"
else
SOF_TRACE_MODE="etrace"
fi
break
fi
done
if [[ -z "${SOF_TRACE_NODE}" ]]; then
echo "[ERROR] 未找到 /sys/kernel/debug/sof/{trace,etrace}(可能权限或内核配置问题)" >&2
echo " 你可以先用 root 查看ls -la /sys/kernel/debug/sof" >&2
exit 1
fi
echo "[INFO] SOF_TRACE_NODE=${SOF_TRACE_NODE}"
echo "[INFO] SOF_TRACE_MODE=${SOF_TRACE_MODE}"
echo
echo "[STEP] 2.3) 记录 SOF debugfs 快照(用于后续定位)"
{
echo "=== snapshot ts=${start_ts_human} ==="
echo "SOF_TRACE_NODE=${SOF_TRACE_NODE}"
echo "SOF_TRACE_MODE=${SOF_TRACE_MODE}"
echo
echo "## ls -la /sys/kernel/debug/sof"
ls -la /sys/kernel/debug/sof 2>&1 || true
echo
for f in fw_version dsp_state ipc4_fw_status ipc4_bldr_status; do
if [[ -e "/sys/kernel/debug/sof/${f}" ]]; then
echo "## cat /sys/kernel/debug/sof/${f}"
cat "/sys/kernel/debug/sof/${f}" 2>&1 || true
echo
fi
done
} > "${sof_debug_snapshot}" 2>&1 || true
echo "[DONE] sof debugfs snapshot: ${sof_debug_snapshot}"
cleanup() {
echo
echo "[STEP] 4) 收集日志窗口 (since ${start_ts_human})"
# Kernel: capture SOF/ASoC/HDMI related lines since start
journalctl -k -b --since "${start_ts_human}" --no-pager 2>/dev/null | \
grep -nE 'sof-audio|snd_sof|sof_ipc3_pcm_hw_params|ipc tx error|STREAM_PCM_PARAMS|ASoC error|set_hw_params|HDMI[0-9]|pcm[0-9]+' \
> "${kernel_log}" || true
# User PipeWire: capture since start
journalctl --user -u pipewire -b --since "${start_ts_human}" --no-pager 2>/dev/null \
> "${pipewire_log}" || true
echo "[DONE] sof-logger: ${sof_log}"
echo "[DONE] kernel window: ${kernel_log}"
echo "[DONE] pipewire window: ${pipewire_log}"
echo
echo "[NEXT] 请把这三份日志发我分析:"
echo " - ${sof_log}"
echo " - ${kernel_log}"
echo " - ${pipewire_log}"
}
trap cleanup INT TERM EXIT
echo
echo "[STEP] 3) 开始抓取 SOF trace前台运行按 Ctrl+C 结束并收集窗口日志)"
echo "[ACTION] 现在请在另一个终端复现一次问题(例如触发 HDMI pcm2 的播放/切换)。"
echo
echo "[INFO] capturing to: ${sof_log}"
echo
# sof-logger 参数说明(关键):
# -l: 传入 .ldc dictionary不是输出文件
# -t: 选择 DMA trace stream会强制读取 /sys/kernel/debug/sof/trace
# -i/-o: 将输入流解码输出到文件
echo "[INFO] NOTE: etrace 通常是“读完当前缓冲就退出”,所以这里使用循环追加,直到 Ctrl+C。"
echo
touch "${sof_log}"
echo "=== sof-trace-capture start ${start_ts_human} ===" >> "${sof_log}"
capture_once() {
local tmp="${LOG_DIR}/.sof-logger_${ts}.tmp"
rm -f "${tmp}"
if [[ "${SOF_TRACE_MODE}" == "trace" ]]; then
"${SOF_LOGGER}" -l "${SOF_LDC}" -t -i "${SOF_TRACE_NODE}" -o "${tmp}" || true
else
# etrace mailbox: do NOT pass -t, otherwise sof-logger will try /sys/kernel/debug/sof/trace
"${SOF_LOGGER}" -l "${SOF_LDC}" -i "${SOF_TRACE_NODE}" -o "${tmp}" || true
fi
if [[ -s "${tmp}" ]]; then
{
echo
echo "=== sof-logger chunk @ $(date '+%F %T') ==="
cat "${tmp}"
} >> "${sof_log}"
fi
rm -f "${tmp}"
}
while true; do
capture_once
sleep 0.2
done