Linux使用strace和perf进行进程调试和性能分析的深度指南

 更新时间:2026年05月28日 08:53:28   作者:STDD  
strace 和 perf 是 Linux 系统性能诊断的两把利刃:strace 追踪进程的系统调用,揭示进程与内核的每次交互;perf 是 Linux 内核内置的性能分析器,能够捕获 CPU 级别的性能事件,本文给大家介绍了Linux使用strace和perf进行进程调试和性能分析的深度指南

当线上服务出现莫名的性能下降、神秘的"文件未找到"错误或奇怪的网络超时,常规的日志分析往往无法给出答案。这时候需要深入内核层面,观察进程的真实行为。

straceperf 是 Linux 系统性能诊断的两把利刃:strace 追踪进程的系统调用,揭示进程与内核的每次交互;perf 是 Linux 内核内置的性能分析器,能够捕获 CPU 级别的性能事件,生成直观的火焰图。掌握这两个工具,能够解决 80% 以上的难以排查的线上问题。

服务器配置

straceperf 是通用的 Linux 诊断工具,适用于任意服务器。推荐使用 雨云服务器 rainyun-com 的2 核 4GB 机型 作为学习和实验环境,注册填优惠码 2026off 领 5 折,以最低成本掌握 Linux 性能分析技能。

本文环境:

  • 操作系统:Ubuntu 22.04 LTS(内核 5.15+)
  • strace:5.16
  • perf:5.15(随内核版本提供)

安装工具

安装 strace

Ubuntu/Debian:

apt install strace -y
strace --version
# strace -- version 5.16

安装 perf

perf 工具与内核版本绑定,需要安装对应版本:

# 查看内核版本
uname -r
# 例如:5.15.0-106-generic

# 安装对应版本的 perf
apt install linux-tools-$(uname -r) linux-tools-generic -y

# 验证安装
perf --version
# perf version 5.15.168

如果出现 “WARNING: perf not found for kernel” 错误,说明内核版本对应的包不在仓库中,可以使用通用包:

apt install linux-tools-generic -y

strace 基础:追踪系统调用

基本用法

追踪一个命令的所有系统调用:

strace ls /tmp

输出中每行是一次系统调用,格式为:

syscall_name(args...) = return_value
execve("/usr/bin/ls", ["ls", "/tmp"], ...) = 0
brk(NULL)                               = 0x5610a8c3b000
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...

附加到运行中的进程

# 获取进程 PID
pgrep nginx
# 例如:1234

# 附加追踪
strace -p 1234

过滤特定类别的系统调用

# 只追踪网络相关系统调用
strace -e trace=network nginx

# 只追踪文件 I/O
strace -e trace=open,read,write,close -p 1234

# 追踪进程与文件系统的交互
strace -e trace=file -p 1234

常用过滤类别:

  • network:socket、connect、send、recv 等
  • file:open、read、write、stat 等
  • process:fork、exec、exit 等
  • memory:mmap、brk、munmap 等
  • signal:kill、sigaction 等

实战一:诊断"文件未找到"错误

应用报告无法找到配置文件,但文件明明存在。使用 strace 追踪文件打开操作:

strace -e trace=openat,stat -p $(pgrep my-app) 2>&1 | grep -E "(ENOENT|config)"

典型输出:

openat(AT_FDCWD, "/etc/my-app/config.yaml", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/app/.config/my-app.yaml", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/etc/my-app.yaml", O_RDONLY) = 5

从输出可以清晰看出:进程按顺序查找多个路径,前两个返回 ENOENT,第三个成功。如果三个都失败,就能知道应用实际在哪些路径寻找配置文件,而不是猜测。

实战二:调试网络连接超时

服务偶发性地无法连接数据库,使用 strace 分析网络行为:

# -T 显示每次系统调用的耗时
strace -T -e trace=network -p $(pgrep my-service) 2>&1 | grep -E "(connect|poll|select)"

输出:

connect(5, {sa_family=AF_INET, sin_port=htons(5432), sin_addr=inet_addr("10.0.0.5")}, 16) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=5, events=POLLOUT|POLLERR}], 1, 5000) = 0 (Timeout) <5.000342>

poll 返回 0 (Timeout) 且耗时 5 秒,说明连接超时。结合 connect 显示的目标 IP 和端口,可以确认是否网络路由或防火墙问题。

实战三:统计系统调用热点

分析某个进程在 30 秒内最频繁调用的系统调用:

# -c 统计系统调用次数,-p 附加进程
timeout 30 strace -c -p $(pgrep nginx) 2>&1

输出:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 45.23    0.234567           5     46914           epoll_wait
 25.11    0.130234           4     32558     156    read
 18.45    0.095672           3     31891           write
  8.32    0.043156          12      3596           sendfile
...

epoll_wait 占 45% 的时间是正常的(Nginx 事件循环),但如果 futex(锁等待)或 nanosleep(主动等待)占比过高,则说明程序存在竞争或轮询问题。

perf 基础:硬件性能计数器

perf stat:分析 CPU 效率

# 分析运行命令的性能计数器
perf stat ls /tmp

# 附加到运行中的进程(收集 10 秒)
perf stat -p $(pgrep nginx) sleep 10

输出:

 Performance counter stats for process id '1234':

      10,234.56 msec task-clock                #    1.000 CPUs utilized
             45      context-switches          #    4.398 /sec
              8      cpu-migrations            #    0.781 /sec
            234      page-faults               #   22.863 /sec
 28,456,789,012      cycles                    #    2.781 GHz
 18,234,567,890      instructions              #    0.64  insn per cycle
    456,789,012      branches                  #   44.635 M/sec
     12,345,678      branch-misses             #    2.70% of all branches

关键指标解读:

  • insn per cycle(IPC):每时钟周期执行的指令数。低于 1.0 说明存在大量等待(缓存缺失、分支预测失败等)
  • branch-misses:分支预测失误率,超过 5% 需要关注
  • cache-misses:添加 -e cache-references,cache-misses 查看缓存命中率

perf top:实时 CPU 热点

# 查看全系统的 CPU 热点函数(类似 htop 但到函数级别)
perf top

# 只关注特定进程
perf top -p $(pgrep nginx)

输出类似:

Samples: 50K of event 'cpu-cycles', 4000 Hz, Event count
Overhead  Shared Object           Symbol
  18.23%  nginx                   [.] ngx_http_process_request
  12.45%  libc-2.35.so            [.] __memcpy_avx_unaligned
   8.91%  nginx                   [.] ngx_regex_exec
   6.78%  [kernel]                [k] copy_user_generic_string

Overhead 列显示函数占总 CPU 时间的百分比,可快速定位性能热点函数。

实战四:perf record 生成调用图

perf top 只能看到单个函数,无法知道调用链。使用 perf record 录制带调用图的性能数据:

# 录制 30 秒的调用图(-g 启用 call graph)
perf record -g -p $(pgrep my-service) sleep 30

# 生成报告
perf report --call-graph=graph

交互式报告中可以展开调用链,查看函数的调用者和被调用者。

实战五:生成火焰图(Flame Graph)

火焰图由 Brendan Gregg 发明,是可视化 CPU 性能热点的最佳工具。X 轴表示 CPU 时间占比,Y 轴表示调用栈深度。

步骤一:安装 FlameGraph 工具

git clone https://github.com/brendangregg/FlameGraph.git /opt/flamegraph

步骤二:录制性能数据

# 录制 60 秒,采样频率 99Hz
perf record -F 99 -g -p $(pgrep my-service) sleep 60

步骤三:生成火焰图

# 将 perf.data 转换为折叠格式
perf script | /opt/flamegraph/stackcollapse-perf.pl > out.folded

# 生成 SVG 火焰图
/opt/flamegraph/flamegraph.pl out.folded > flamegraph.svg

步骤四:下载并查看

# 用 scp 下载到本地(在本地终端执行)
scp root@server-ip:/root/flamegraph.svg ~/Desktop/

# 用浏览器打开 SVG 文件,可以点击放大

解读火焰图

  • 宽块:CPU 时间集中的函数,是优化重点
  • 平顶:表示该函数本身消耗大量 CPU(非其调用的子函数)
  • 高塔:深层调用栈,通常是递归或复杂库调用
  • 颜色:随机分配,没有特别含义(红/黄不代表问题)

perf sched:分析调度延迟

系统响应延迟但 CPU 利用率不高?可能是调度延迟问题:

# 录制调度事件
perf sched record sleep 10

# 生成延迟报告
perf sched latency

输出会显示各任务的最大调度延迟和平均延迟,帮助识别 RT 任务或 I/O 密集型任务导致的调度不公平问题。

strace 与 perf 的使用场景对比

场景推荐工具原因
文件找不到strace追踪 openat 系统调用
网络连接失败strace追踪 connect/poll 行为
CPU 使用率高perf top + 火焰图定位热点函数
响应延迟高但 CPU 不高strace -T + perf sched找出耗时的系统调用或调度延迟
缓存命中率低perf stat查看硬件缓存计数器

straceperf 是每位 Linux 工程师必须掌握的核心工具。strace 让你看到进程与内核的每次对话,解决"为什么失败"的问题;perf 和火焰图让你看到 CPU 时间的分布,解决"为什么慢"的问题。两者结合,几乎没有无法排查的性能问题。

以上就是Linux使用strace和perf进行进程调试和性能分析的深度指南的详细内容,更多关于Linux strace和perf进程调试和性能分析的资料请关注脚本之家其它相关文章!

相关文章

  • Apache日志的一些操作命令技巧

    Apache日志的一些操作命令技巧

    这篇文章主要介绍了Apache日志的一些操作命令技巧,对于查看服务器负载等情况时非常便捷实用,需要的朋友可以参考下
    2015-07-07
  • Linux中Docker遇到报port is already allocated错误

    Linux中Docker遇到报port is already allocated错误

    在Linux系统中,如果尝试绑定一个网络服务到一个已经被其他进程使用的端口上,你会遇到“port is already allocated”错误,这意味着该端口已经被另一个进程占用,因此无法再次被分配给任何新的服务
    2024-06-06
  • linux如何将sda分区扩容

    linux如何将sda分区扩容

    这篇文章主要介绍了linux如何将sda分区扩容问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • Linux系统安装Samba服务器实现过程

    Linux系统安装Samba服务器实现过程

    本文介绍了如何在CentOS7系统上安装和配置Samba服务器,以实现Windows和Linux系统之间的文件共享
    2026-02-02
  • Linux中查询磁盘类型的命令详解

    Linux中查询磁盘类型的命令详解

    这篇文章主要为大家详细介绍了Linux中查询磁盘类型命令的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下
    2023-08-08
  • linux服务器安装SonarQube代码检测工具的详细步骤

    linux服务器安装SonarQube代码检测工具的详细步骤

    这篇文章主要介绍了linux服务器安装SonarQube代码检测工具,本文分步骤给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • linux解压缩 xxx.jar文件进行内部操作过程

    linux解压缩 xxx.jar文件进行内部操作过程

    这篇文章主要介绍了linux解压缩 xxx.jar文件进行内部操作,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-07-07
  • Ubuntu下安装和卸载软件的方法分享

    Ubuntu下安装和卸载软件的方法分享

    这篇文章主要介绍了Ubuntu下安装和卸载软件的方法,文中介绍的非常详细,相信对大家具有一定的参考价值,需要的朋友下面来一起看看吧。
    2017-03-03
  • Linux下一个智能重启Apache服务器的脚本分享

    Linux下一个智能重启Apache服务器的脚本分享

    这篇文章主要介绍了Linux下一个智能重启Apache服务器的脚本分享,当检测到脚本中所设定的服务器异常情况下便可执行自动重启,需要的朋友可以参考下
    2015-07-07
  • Git提交日志修改方法实例汇总

    Git提交日志修改方法实例汇总

    这篇文章主要介绍了Git提交日志修改方法实例汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论