嵌入式Linux远程调试Skill:Agent全自动分析内核层
从 Windows 远程调试嵌入式Linux,分析性能与稳定性
一套开源Agent的Skill,能使 Agent 在 Windows 上通过 SSH 一键完成嵌入式 Linux 设备的性能分析、稳定性诊断和内核级 trace 可视化。
开源链接:
https://gitee.com/leo_liu28/embedded-linux-debug-skills.git
前言:嵌入式性能分析的痛点
做嵌入式 Linux 开发的同学一定遇到过这些场景:
- 设备部署在现场,只能通过 SSH 远程登录,没有图形界面
- 出了性能问题想抓 ftrace,但每次都要手敲一堆 debugfs 命令
- 好不容易抓到了 trace 数据,导入 Perfetto 却报格式错误——因为设备跑的是 RT 内核
perf、iostat等工具在精简的嵌入式 rootfs 上根本没装- 一次现场机会,需要把 CPU/内存/IO/稳定性数据全部打包带走,让AI全流程自行分析
现在 Agent 在Java等互联网开发环境大用特用,但是嵌入式环境始终差点意思。所以针对嵌入式Linux环境写了这套skills,后续可增加iomem查看寄存器调试硬件的功能。将embedded-linux-debug文件夹打包放进.qoder或.claude的skills目录下,即可开箱使用。
项目介绍
Embedded Linux Remote Debug Skill 是一套面向嵌入式场景的远程调试工具集,核心能力:
| 能力 | 说明 |
|---|---|
| SSH 自动检测 | 自动识别 Windows 上的 OpenSSH / PuTTY 客户端 |
| 一键诊断 | CPU / 内存 / IO / 稳定性四大维度,单脚本搞定 |
| ftrace + Perfetto | 一键抓取 → 导入 Perfetto 可视化,支持 RT 内核 |
| 工具缺失降级 | perf/iostat 不存在时自动 fallback 到 /proc |
| pstore 崩溃恢复 | 读取 ramoops 保存的内核崩溃 dmesg |
适合谁用:
- 嵌入式 Linux BSP/驱动工程师
- 系统性能优化工程师
- 现场部署与运维人员
- 对 Linux 内核调度/中断行为感兴趣的开发者
环境准备
Windows 主机
| 组件 | 要求 |
|---|---|
| SSH 客户端 | OpenSSH(Win10 1809+ 自带)或 PuTTY(plink/pscp) |
| Python 3 | RT 内核 trace 转换时需要 |
| 网络 | 能访问嵌入式设备 IP |
嵌入式 Linux 设备
| 组件 | 要求 |
|---|---|
| SSH 服务 | dropbear 或 openssh-server |
| 权限 | root(ftrace/perf 操作必需) |
| 内核配置 | CONFIG_FUNCTION_TRACER、CONFIG_PERF_EVENTS(按需) |
| 建议工具 | perf strace iostat(缺失可自动降级) |
核心功能演示
1. SSH 连接与自动检测
在 Windows 上运行检测脚本,自动识别可用的 SSH 客户端:
powershell -ExecutionPolicy Bypass -File scripts/detect-ssh.ps1
支持两种连接方式:
# OpenSSH(推荐)
ssh root@192.168.1.100 "echo ok && uname -a"
# PuTTY plink
plink -ssh -pw <password> root@192.168.1.100 "uname -a"
推荐使用密钥认证实现免密登录:
ssh-keygen -t ed25519
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh root@192.168.1.100 "mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys"
2. CPU/内存/IO/稳定性一键诊断
上传脚本 → 远程执行 → 取回报告,三步完成:
# 上传所有脚本
scp scripts/*.sh root@192.168.1.100:/tmp/
# 一键综合诊断
ssh root@192.168.1.100 "chmod +x /tmp/*.sh; /tmp/full-diagnosis.sh"
# 取回打包报告
scp root@192.168.1.100:/tmp/diagnosis_output.tar.gz .
也可以针对特定维度单独执行:
# CPU 分析(指定 PID 和采样时长)
ssh root@192.168.1.100 "/tmp/cpu-profiling.sh 1234 15"
# 内存分析
ssh root@192.168.1.100 "/tmp/memory-analysis.sh 1234"
# IO 分析
ssh root@192.168.1.100 "/tmp/io-analysis.sh 1234 10"
# 稳定性排查
ssh root@192.168.1.100 "/tmp/stability-check.sh"
3. ftrace Perfetto 抓取与可视化(重点)
这是本项目最核心的能力——将嵌入式设备的内核调度行为以可视化 timeline 呈现。
整体工作流
┌─────────────┐ SSH ┌─────────────┐ SCP ┌─────────────┐ 导入 ┌─────────────┐
│ Windows主机 │ ────────→ │ 嵌入式设备 │ ──────→ │ 本地文件 │ ───────→ │ Perfetto │
│ (控制端) │ │ ftrace抓取 │ │ ftrace.txt │ │ 可视化UI │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│
RT内核?需转换
↓
┌─────────────┐
│ rt_trace_ │
│ converter.py│
└─────────────┘
Step 1:上传并执行抓取脚本
scp scripts/ftrace-capture.sh root@192.168.1.100:/tmp/
ssh root@192.168.1.100 "chmod +x /tmp/ftrace-capture.sh; /tmp/ftrace-capture.sh /tmp/ftrace.txt 10"
脚本自动完成以下配置(摘自 ftrace-capture.sh 关键逻辑):
TRACE_DIR=/sys/kernel/debug/tracing
# 启用 Perfetto 关键选项
echo 1 > ${TRACE_DIR}/options/irq-info # Perfetto依赖此字段渲染中断泳道
echo 1 > ${TRACE_DIR}/options/record-tgid # 记录线程组ID用于进程分组
echo global > ${TRACE_DIR}/trace_clock # 全局时钟,多CPU事件对齐
echo 280000 > ${TRACE_DIR}/buffer_size_kb # 约280MB环形缓冲区
# 启用调度+中断+块设备事件
echo 1 > ${TRACE_DIR}/events/sched/sched_switch/enable
echo 1 > ${TRACE_DIR}/events/sched/sched_wakeup/enable
echo 1 > ${TRACE_DIR}/events/irq/irq_handler_entry/enable
echo 1 > ${TRACE_DIR}/events/irq/irq_handler_exit/enable
echo 1 > ${TRACE_DIR}/events/block/enable
# 定时采集
echo 1 > ${TRACE_DIR}/tracing_on
sleep ${DURATION}
echo 0 > ${TRACE_DIR}/tracing_on
Step 2:取回 trace 文件
scp root@192.168.1.100:/tmp/ftrace.txt ./results/
Step 3:导入 Perfetto 可视化
打开 https://ui.perfetto.dev → 拖入 ftrace.txt → 即可看到 CPU 调度泳道图、中断时间线、进程唤醒链路。
4. RT 内核 trace 转换(7位→4位 flags)
问题背景: Linux RT(PREEMPT_RT)补丁内核的 ftrace 输出使用 7位 flags 格式,而 Perfetto 只认标准的 4位格式,直接导入会报错或丢失中断泳道。
如何判断?
打开 trace 文件,观察 flags 列:
# 标准内核(4位)— 可直接导入
<idle>-0 [001] dnh1 1486.862171: irq_handler_entry: irq=3 name=xxx
# RT内核(7位)— 需要转换!
<idle>-0 (-------) [001] dn.h1.. 1486.862171: irq_handler_entry: irq=3 name=xxx
7位 flags 结构解析
| 位置 | 含义 | 标准内核 | RT内核 |
|---|---|---|---|
| 0 | irqs-off | ✓ | ✓ |
| 1 | need-resched | ✓ | ✓ |
| 2 | need-resched-lazy | — | RT新增 |
| 3 | hardirq/softirq | ✓ | ✓ |
| 4 | preempt-depth | ✓ | ✓ |
| 5 | preempt-lazy-depth | — | RT新增 |
| 6 | migrate-disable | — | RT新增 |
转换映射: 取 RT[0]RT[1]RT[3]RT[4] → 标准 4 位
执行转换
python scripts/rt_trace_converter.py ./results/ftrace.txt ./results/ftrace_perfetto.txt
转换脚本的核心逻辑(摘自 rt_trace_converter.py):
def convert_rt_flags(rt7: str) -> str:
"""
RT 7位 -> 标准4位
映射: RT[0]->STD[0], RT[1]->STD[1], RT[3]->STD[2], RT[4]->STD[3]
示例: dn.h1.. -> dnh1
"""
return f"{rt7[0]}{rt7[1]}{rt7[3]}{rt7[4]}"
脚本还会:
- 过滤 RT 专有注释行(need-resched-lazy 等 Perfetto 不识别的行)
- 输出转换报告(总行数、转换行数、事件统计)
- 验证 irq entry/exit 事件平衡性
- 检查转换后是否包含 h/s 标志(Perfetto 渲染中断泳道的依据)
5. strace 单线程精确分析
多线程应用中,整进程 strace 噪声太大。我们可以精确跟踪单个线程:
# 查看目标进程的所有线程
ssh root@192.168.1.100 "ls /proc/1234/task/"
# 对指定线程进行精确跟踪(20秒超时保护)
ssh root@192.168.1.100 "timeout 20s strace -tt -yy -T -v -e trace=all -o /tmp/strace_tid.log -s 1024 -p 1235"
# 取回分析
scp root@192.168.1.100:/tmp/strace_tid.log ./results/
关键参数:-tt(微秒时间戳)、-yy(fd 解析为路径)、-T(每次调用耗时)、timeout(嵌入式环境必加,防止 strace 无限运行)。
6. pstore/ramoops 崩溃日志恢复
设备异常重启后,通过 ramoops 预留内存恢复崩溃时的内核日志:
# 查看是否有崩溃日志
ssh root@192.168.1.100 "ls -la /var/lib/systemd/pstore/"
# 读取崩溃 dmesg
ssh root@192.168.1.100 "cat /var/lib/systemd/pstore/dmesg-ramoops-*"
# 取回所有崩溃日志
scp root@192.168.1.100:/var/lib/systemd/pstore/* ./results/pstore/
前提: 内核需启用
CONFIG_PSTORE+CONFIG_PSTORE_RAM,且设备树或启动参数中配置了 ramoops 预留内存区域。
技术亮点
设计思路
┌─────────────────────────────────────────────────────┐
│ 设计原则 │
├─────────────────────────────────────────────────────┤
│ 1. 嵌入式资源友好 — 脚本轻量,采集后立即释放缓冲 │
│ 2. 工具缺失 fallback — iostat/perf 不存在自动降级 │
│ 3. Perfetto 兼容优先 — irq-info/record-tgid/global │
│ 4. RT 内核全覆盖 — 7位flags自动转换 │
│ 5. 一次现场机会 — full-diagnosis 一键全量打包 │
└─────────────────────────────────────────────────────┘
关键决策
- ftrace 抓取采用脚本方式而非手动命令 — 配置项多达 10+ 条 debugfs 写入,手动操作易遗漏且不可复现
- Perfetto 兼容配置内置 — 不需要用户了解
irq-info、record-tgid、trace_clock等细节 - 采集后立即缩小 buffer —
echo 100 > buffer_size_kb,避免嵌入式设备内存长时间被占用 - RT trace 转换独立为 Python 脚本 — 在 Windows 本地执行,不消耗嵌入式设备资源
使用效果
诊断完成后,工具会生成结构化的报告文件,便于后续归档与追溯:
# 嵌入式设备诊断报告
## 基本信息
- 设备型号:i.MX8M Plus EVK
- 内核版本:5.15.71-rt50
- 故障现象:周期性响应延迟 >50ms
## 关键发现
| 类别 | 现象 | 证据来源 |
| ---- | ---- | -------- |
| CPU | kworker 占用 85% | cpu_report.txt |
| 中断 | IRQ 35 每秒触发 12000+ 次 | Perfetto 中断泳道 |
| 调度 | 高优先级线程唤醒延迟 8ms | sched_wakeup 事件 |
## 根因分析
IRQ 35(SPI DMA 完成中断)触发过频,kworker 处理积压导致调度延迟。
Perfetto 可视化效果可以清晰看到:
- 各 CPU 核心的任务切换时间线
- 中断处理的进入/退出及持续时长
- 进程间的唤醒因果链
开源地址与后续计划
GitHub: https://github.com/xxx/embedded-linux-debug(即将发布)
后续计划
- 支持 Trace Compass 格式输出
- 添加 eBPF 采集模式(5.x+ 内核)
- 集成 FlameGraph 火焰图生成
- 支持串口(UART)作为备用通道
- Web Dashboard 报告可视化
总结
本项目提供了一套从 Windows 远程调试嵌入式 Linux 设备的Skill——从 SSH 连接检测、一键多维诊断,到 ftrace Perfetto 可视化分析(含 RT 内核兼容),再到 pstore 崩溃日志恢复。所有脚本均为嵌入式资源受限环境设计,工具缺失自动降级,采集完成立即释放资源。无论是日常性能调优还是现场紧急排障,都能帮你用最少的操作获取最全面的诊断数据,让Agent能够全流程自动分析BUG。
如果这篇文章对你有帮助,欢迎点赞、收藏、转发,也欢迎到 Gitee 上 Star 支持!
本文基于实际嵌入式项目调试经验整理,所有脚本代码均已开源。
更多推荐



所有评论(0)