ZhiBing's blog(码上看世界) ZhiBing's blog(码上看世界)
首页
  • Linux工具链

    • shell命令
  • 构建

    • CMake
    • Makefile
  • 版本管理

    • Git
    • Github
  • IDE及工具

    • vscode
    • CLion
  • 设计模式

    • 设计原则
  • 编程语言

    • C++
    • Go
    • Python
    • Shell
  • 调试

    • gdb
  • 开发者测试

    • gtest
  • 系统支撑

    • 操作系统
  • 性能优化

    • 编译优化选项
    • perf
    • valgrind
  • 容器

    • Docker
  • 微服务

    • Rancher
  • 其他
  • 随笔
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

ZhiBing Zheng

时间会回答成长
首页
  • Linux工具链

    • shell命令
  • 构建

    • CMake
    • Makefile
  • 版本管理

    • Git
    • Github
  • IDE及工具

    • vscode
    • CLion
  • 设计模式

    • 设计原则
  • 编程语言

    • C++
    • Go
    • Python
    • Shell
  • 调试

    • gdb
  • 开发者测试

    • gtest
  • 系统支撑

    • 操作系统
  • 性能优化

    • 编译优化选项
    • perf
    • valgrind
  • 容器

    • Docker
  • 微服务

    • Rancher
  • 其他
  • 随笔
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • 编程语言

  • 调试

    • gdb

    • strace

      • strace抓取隐藏错误
        • 一、什么是 strace
        • 二、核心用法
          • 2.1 基础命令
          • 2.2 常用选项
        • 三、抓取隐藏错误的实战场景
          • 3.1 文件操作错误
          • 3.2 网络连接问题
          • 3.3 权限问题
          • 3.4 内存映射问题
          • 3.5 进程间通信错误
          • 3.6 库文件加载问题
        • 四、高级技巧
          • 4.1 只关注失败的调用
          • 4.2 带时间分析的追踪
          • 4.3 附着到运行中的进程
          • 4.4 输出到文件并分析
        • 五、错误码速查表
        • 六、实战案例
          • 案例 1:程序启动失败但无报错
          • 案例 2:程序卡住不动
          • 案例 3:权限问题排查
        • 七、注意事项
        • 八、与其他工具的配合
        • 总结
  • 开发者测试

  • 系统支撑

  • 性能优化

  • 小技巧

  • 通用领域
  • 调试
  • strace
zhengzhibing
2026-06-06
目录

strace抓取隐藏错误

# strace 抓取隐藏错误

# 一、什么是 strace

strace 是 Linux 下的系统调用追踪工具,能够拦截并记录进程执行过程中的所有系统调用(syscall)以及收到的信号。

核心原理:

  • 使用 ptrace 系统调用附加到目标进程
  • 在每个系统调用前后触发断点
  • 记录系统调用的参数、返回值和耗时

为什么能发现隐藏错误: 很多错误不会直接抛出异常,但会在系统调用层面留下痕迹:

  • 文件操作失败(权限不足、路径不存在)
  • 网络连接异常(连接超时、拒绝)
  • 内存映射问题(mmap 失败)
  • 进程间通信错误(管道破裂、信号丢失)

# 二、核心用法

# 2.1 基础命令

# 追踪进程的所有系统调用
strace <command>

# 追踪已运行的进程
strace -p <pid>

# 输出到文件
strace -o trace.log <command>
1
2
3
4
5
6
7
8

# 2.2 常用选项

选项 作用 示例
-e trace=file 只追踪文件相关调用 strace -e trace=file ls
-e trace=network 只追踪网络调用 strace -e trace=network curl http://example.com
-e trace=process 只追踪进程调用 strace -e trace=process fork
-e trace=memory 只追踪内存调用 strace -e trace=memory ./app
-f 跟踪子进程 strace -f ./app
-t 显示时间戳 strace -t <command>
-T 显示每个调用耗时 strace -T <command>
-c 统计摘要 strace -c <command>
-s 设置字符串长度 strace -s 1024 <command>

# 三、抓取隐藏错误的实战场景

# 3.1 文件操作错误

场景: 程序静默失败,没有输出错误信息

# 追踪文件操作
strace -e trace=file -f ./my_program 2>&1 | grep -E "(ENOENT|EACCES|EPERM)"
1
2

常见隐藏错误模式:

open("/etc/config.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
access("/var/run/app.pid", W_OK)      = -1 EACCES (Permission denied)
stat("/usr/lib/libfoo.so", 0x7ffd...) = -1 EACCES (Permission denied)
1
2
3

# 3.2 网络连接问题

场景: 程序卡住但没有超时错误

# 追踪网络调用
strace -e trace=network -T ./my_program 2>&1 | grep -E "(ETIMEDOUT|ECONNREFUSED|ECONNRESET)"
1
2

常见隐藏错误模式:

connect(5, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ETIMEDOUT (Connection timed out)
sendto(5, "SELECT...", 1024, 0, NULL, 0) = -1 ECONNRESET (Connection reset by peer)
1
2

# 3.3 权限问题

场景: 程序在某些用户下失败,但报错信息不明确

# 统计系统调用错误
strace -c -f ./my_program 2>&1 | tail -20
1
2

关注:

  • EPERM (Operation not permitted) - 权限不足
  • EACCES (Permission denied) - 访问被拒绝
  • EEXIST (File exists) - 文件已存在(可能是锁文件)

# 3.4 内存映射问题

场景: 程序崩溃但 core dump 信息不明确

# 追踪内存操作
strace -e trace=memory -f ./my_program 2>&1 | grep -E "(ENOMEM|MAP_FAILED)"
1
2

常见错误模式:

mmap(NULL, 1073741824, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap(0x7f0000000000, 4096, PROT_READ, MAP_FIXED|MAP_PRIVATE, 3, 0) = MAP_FAILED (-1 errno = 13)
1
2

# 3.5 进程间通信错误

场景: 管道或共享内存通信失败

# 追踪进程调用
strace -e trace=process,signal -f ./my_program 2>&1 | grep -E "(SIGPIPE|ECHILD)"
1
2

常见错误模式:

write(4, "data", 4) = -1 EPIPE (Broken pipe)
wait4(-1, 0x7ffd..., WNOHANG|WUNTRACED, NULL) = -1 ECHILD (No child processes)
1
2

# 3.6 库文件加载问题

场景: 动态库加载失败但报错不清晰

# 追踪文件操作,关注 .so 文件
strace -e trace=file ./my_program 2>&1 | grep "\.so"
1
2

常见错误模式:

openat(AT_FDCWD, "./libfoo.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT
openat(AT_FDCWD, "/usr/lib/libfoo.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT
1
2

# 四、高级技巧

# 4.1 只关注失败的调用

# 过滤返回值为错误的调用
strace -e inject=error:retval=error ./my_program

# 或者用 grep 过滤
strace ./my_program 2>&1 | grep "= -"
1
2
3
4
5

# 4.2 带时间分析的追踪

# 追踪并显示耗时,找出慢操作
strace -T -e trace=file,network ./my_program 2>&1 | awk '{if($NF+0 > 0.1) print}'
1
2

# 4.3 附着到运行中的进程

# 找到目标进程
ps aux | grep my_program

# 附着追踪(Ctrl+C 停止)
strace -p <pid> -e trace=file -f
1
2
3
4
5

# 4.4 输出到文件并分析

# 保存完整追踪
strace -f -o /tmp/trace.log ./my_program

# 分析错误统计
grep -E "= -[A-Z]" /tmp/trace.log | awk '{print $NF}' | sort | uniq -c | sort -rn | head -20
1
2
3
4
5

# 五、错误码速查表

错误码 含义 常见原因
ENOENT No such file or directory 文件路径不存在
EACCES Permission denied 权限不足
EPERM Operation not permitted 无操作权限
ECONNREFUSED Connection refused 连接被拒绝
ETIMEDOUT Connection timed out 连接超时
ECONNRESET Connection reset 连接被重置
ENOMEM Cannot allocate memory 内存不足
EPIPE Broken pipe 管道断裂
ECHILD No child processes 子进程不存在
EEXIST File exists 文件已存在(如锁文件)
EROFS Read-only file system 只读文件系统

# 六、实战案例

# 案例 1:程序启动失败但无报错

# 问题:程序启动后立即退出,没有错误输出

# 分析
strace -f -o /tmp/trace.log ./my_program
grep "= -" /tmp/trace.log | head -20

# 发现:
# openat(AT_FDCWD, "./config.yaml", O_RDONLY) = -1 ENOENT
# 结论:缺少配置文件
1
2
3
4
5
6
7
8
9

# 案例 2:程序卡住不动

# 问题:程序运行一段时间后卡住

# 分析
strace -p <pid> -T -e trace=network

# 发现:
# connect(5, ..., 16) = 0  (0.000123s)
# write(5, "query", 5) = 5  (0.000089s)
# read(5, 0x7ffd..., 8192)   (30.000000s) <unfinished ...>
# 结论:数据库查询超时
1
2
3
4
5
6
7
8
9
10

# 案例 3:权限问题排查

# 问题:普通用户运行失败,root 正常

# 分析
strace -e trace=file,openat ./my_program 2>&1 | grep -E "EACCES|EPERM"

# 发现:
# openat(AT_FDCWD, "/var/log/app.log", O_WRONLY|O_CREAT) = -1 EACCES
# 结论:日志目录权限不足
1
2
3
4
5
6
7
8

# 七、注意事项

  1. 性能影响: strace 会显著降低程序执行速度,生产环境慎用
  2. 安全风险: strace 需要 ptrace 权限,可能被安全策略禁止
  3. 多线程程序: 使用 -f 参数跟踪所有线程
  4. 输出量大: 使用 -e trace= 过滤,避免信息过多
  5. 内核版本: 某些选项在老版本内核上可能不支持

# 八、与其他工具的配合

工具 配合 strace 的用途
ltrace 追踪库函数调用
perf 性能分析和热点定位
gdb 调试程序逻辑错误
dmesg 查看内核错误日志
journalctl 查看系统服务日志

# 总结

strace 的核心价值在于:它能看到程序与操作系统交互的真实情况。

当程序行为异常但没有明显错误信息时,strace 能帮你:

  1. 发现失败的系统调用
  2. 看到实际的参数和返回值
  3. 定位权限、路径、连接等隐蔽问题
  4. 分析程序的执行流程

记住:程序可以对用户撒谎(没有错误输出),但无法对内核撒谎(系统调用记录)。

#strace#调试#系统调用#隐藏错误
打印数组下标
GTest Day 0 —— 编译GoogleTest

← 打印数组下标 GTest Day 0 —— 编译GoogleTest→

最近更新
01
通过公网安全访问 OpenClaw
06-06
02
noexcept函数抛出异常会怎么样
07-14
03
修改程序的启动函数
07-13
更多文章>
Theme by Vdoing | Copyright © 2022-2026 ZhBing Zheng | 粤ICP备2022062743号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式