当前位置: 首页 > news >正文

linux跟踪调试进程异常的方法

在 Linux 环境下定位 CPU 占用 100% 的异常进程,可以按照以下步骤逐步排查:


1. 定位问题进程

1.1 使用 tophtop 工具
  • 命令
top          # 实时查看进程资源占用
htop         # 更友好的交互式工具(需安装)
  • 操作
    • P(大写)按 CPU 使用率排序。
    • 记录目标进程的 PID(进程 ID)和 CPU%
1.2 使用 ps 快速过滤
ps aux --sort=-%cpu | head -n 10   # 按 CPU 降序列出前 10 个进程

2. 分析进程行为

2.1 查看进程的线程状态
  • 命令
top -H -p <PID>      # 查看进程的线程级 CPU 占用
- 按 `P` 排序,找到高 CPU 占用的线程 TID。
- 将 TID 转换为十六进制(用于后续分析): 
printf "%x\n" <TID>
2.2 使用 strace 跟踪系统调用
  • 命令
strace -p <PID> -T -f -o strace.log   # 跟踪进程的系统调用并保存到文件
strace -f -s 1024 -o trace.log  -p <PID> #使用更详细的strace
- 分析重点: * 是否有大量重复的系统调用(如 `read`/`write`)。* 是否卡在某个系统调用(如死锁或 I/O 阻塞)。
2.3 使用 perf 分析性能瓶颈
  • 安装(如未安装):
apt install linux-tools-common linux-tools-$(uname -r)  # Debian/Ubuntu
yum install perf                                        # CentOS/RHEL
  • 命令
perf top -p <PID>                             # 实时查看进程的热点函数
perf record -p <PID> -g -- sleep 30           # 采样 30 秒生成报告
perf report                                   # 分析采样结果
- 输出:显示占用 CPU 最多的函数或代码路径。

3. 查看堆栈信息(需调试符号)

3.1 使用 gdb 附加到进程
  • 命令
gdb -p <PID>                     # 附加到进程
(gdb) thread apply all bt        # 查看所有线程的堆栈
(gdb) detach                     # 退出时分离进程
- 注意:`gdb` 会暂停进程,操作需谨慎。
3.2 通过 /proc 文件系统获取堆栈
cat /proc/<PID>/stack              # 查看内核态堆栈(需 root)

4. 检查日志和代码

4.1 查看进程日志
journalctl -u <服务名>          # 查看 systemd 服务日志
tail -f /var/log/<应用日志>     # 跟踪应用日志
4.2 检查代码逻辑
  • 如果是自研程序:
    • 检查是否存在死循环、未优化的算法(如递归爆炸)。
    • 使用调试工具(如 gdbvalgrind)复现问题。

5. 其他工具

5.1 pidstat(统计进程资源)
pidstat -p <PID> 1 5          # 每秒采样一次,共 5 次
5.2 vmstat(系统整体状态)
vmstat 1                     # 每秒刷新一次系统资源统计
5.3 bpftrace(高级动态追踪)
bpftrace -e 'profile:hz:99 { @[ustack] = count(); }'  # 捕获用户态堆栈

6. 临时应急措施

  • 降低进程优先级
renice -n 19 -p <PID>     # 将进程优先级设为最低(19)
  • 终止进程(谨慎操作):
kill -9 <PID>             # 强制终止进程(最后手段)

总结

  1. 定位进程 → top/htop/ps
  2. 分析线程 → top -H -p PID
  3. 跟踪调用 → strace/perf
  4. 查看堆栈 → gdb / proc/PID/stack
  5. 检查日志 → journalctl/应用日志
  6. 优化或终止 → 修复代码或 kill
http://www.xdnf.cn/news/200575.html

相关文章:

  • Verilog基础:生成块结构(Generate)
  • 将python程序创建成可以在扣子中运行的插件
  • CH592/CH582 触摸按键应用开发实例讲解
  • 面向城市治理的AI集群空域融合模型
  • 数据仓库建模:方法、技巧与实践
  • 罗马数字转整数(简单)
  • pidstat 使用教程:功能介绍及实战示例
  • 用jmeter压测接口,并生成压测报告
  • 工业通讯现场中关于EtherCAT转TCPIP网关的现场应用
  • 初识c++
  • Miniconda Windows10版本下载和安装
  • 工业园区工厂企业数字IP广播应急呼叫对讲系统:数字IP广播极大提升工厂企业管理效率与应急响应效能
  • JAVA实现将富文本内容插入已有word文档并下载(dock4j+jsoup)
  • 【OSG学习笔记】Day 12: 回调机制——动态更新场景
  • Vue 3 vuedraggable 例子
  • AI网文热门题材生成用什么?小说创作工具来帮忙
  • C++中的智能指针
  • 双向流-固计算前处理和耦合设置
  • tanstack动态路由 + router/ 目录管理方案
  • 树莓派学习专题<12>:使用x264库实施H264编码--Linux和Windows上的部署
  • OpenVLA-OFT
  • 谷歌政策松绑?!3月仅下架4.8万款App,同比减少50%
  • Spring生命周期
  • Linux系统编程---exec簇:进程的加载与替换
  • 安装qt4.8.7
  • 软件评测:从多维度看其界面、功能、性能稳定性如何?
  • Java后端开发day38--不可变集合Stream流
  • Java后端接口调用拦截处理:注解与拦截器的实现
  • STM32实现SPI转USB虚拟串口输出(实测40M时钟不丢包)
  • 报表工具:企业数据决策的“智能翻译官“