banner
NEWS LETTER

Linux 开发进阶:调试、日志、性能分析与线上排错

Scroll down

一、为什么调试能力很重要

Linux 应用开发真正的难点不只是写代码,而是程序出问题时能不能定位。程序可能在你的机器上正常,在服务器上崩溃;可能测试环境正常,生产环境慢;也可能偶发死锁、内存泄漏、文件句柄耗尽。

调试和排错要形成固定流程:

1
确认现象 -> 收集信息 -> 缩小范围 -> 验证假设 -> 修复 -> 回归

二、编译时保留调试信息

开发阶段建议使用:

1
gcc main.c -o app -Wall -Wextra -g -O0

说明:

  • -g:生成调试信息。
  • -O0:关闭优化,调试时变量和代码更接近源码。
  • -Wall -Wextra:打开常用警告。

发布版本可以使用:

1
gcc main.c -o app -O2

如果线上需要分析 core dump,最好保留对应版本的带符号二进制或独立调试符号。

三、GDB 基础

启动:

1
gdb ./app

常用命令:

1
2
3
4
5
6
7
8
9
break main
run
next
step
print var
backtrace
info locals
continue
quit

调试带参数程序:

1
gdb --args ./app --config app.conf --port 8080

进入 GDB 后:

1
run

四、Core Dump

开启 core:

1
ulimit -c unlimited

运行程序崩溃后,如果生成 core 文件:

1
gdb ./app core

查看调用栈:

1
backtrace

查看当前帧变量:

1
info locals

core dump 是定位崩溃问题最直接的证据。不要只看日志里的 Segmentation fault,要尽量拿到 core 文件。

五、strace

strace 用来观察系统调用。

查看全部系统调用:

1
strace ./app

跟踪文件相关调用:

1
strace -e openat,read,write,close ./app

跟踪网络:

1
strace -e trace=network ./app

统计耗时:

1
strace -c ./app

常见用途:

  • 程序找不到配置文件。
  • 动态库加载失败。
  • 网络连接失败。
  • 权限不足。
  • 程序卡在某个系统调用。

六、lsof 和文件句柄

查看进程打开了哪些文件:

1
lsof -p <pid>

查看端口占用:

1
lsof -i :8080

如果程序运行一段时间后报:

1
Too many open files

说明文件描述符可能泄漏,或者系统限制太低。

查看限制:

1
ulimit -n

七、top、htop 和 ps

查看整体资源:

1
top

更友好的交互工具:

1
htop

查看某个进程:

1
ps aux | grep app

按 CPU 排序:

1
ps aux --sort=-%cpu | head

按内存排序:

1
ps aux --sort=-%mem | head

八、perf 性能分析

安装:

1
sudo apt install -y linux-tools-common linux-tools-generic

采样:

1
sudo perf record -g ./app

查看报告:

1
sudo perf report

如果程序已经在运行:

1
sudo perf top -p <pid>

perf 适合分析 CPU 热点。不要凭感觉优化,先找到真正耗时的位置。

九、内存问题

常见内存问题:

  • 内存泄漏。
  • 越界访问。
  • use-after-free。
  • double free。
  • 栈溢出。

可以使用 AddressSanitizer:

1
2
gcc main.c -o app -g -fsanitize=address -fno-omit-frame-pointer
./app

也可以使用 Valgrind:

1
valgrind --leak-check=full ./app

AddressSanitizer 速度更快,适合开发阶段;Valgrind 不需要重新编译,但运行慢。

十、日志设计

好日志应该包含:

  • 时间。
  • 级别。
  • 模块。
  • 关键参数。
  • 错误码。
  • 请求 id 或任务 id。

示例:

1
2
2026-06-21 11:00:00 INFO server listen port=8080
2026-06-21 11:00:03 ERROR open config failed path=/etc/app.conf errno=2

不好的日志:

1
2
3
error
failed
something wrong

这类日志没有上下文,出了问题仍然要重新复现。

十一、线上排错流程

推荐顺序:

  1. 看服务状态:systemctl status app
  2. 看日志:journalctl -u app -n 200
  3. 看进程:ps aux | grep app
  4. 看端口:ss -lntp
  5. 看资源:top
  6. 看文件句柄:lsof -p <pid>
  7. 看系统调用:strace -p <pid>
  8. 看性能热点:perf top -p <pid>
  9. 必要时抓包:tcpdump

十二、总结

Linux 调试不是背命令,而是建立排错路径。先确认程序是否运行,再看日志和资源,再深入到系统调用、core dump、性能采样。

能写代码只是开发的一半,能在复杂环境里把问题定位出来,才是 Linux 应用开发的关键能力。

其他文章
目录导航 置顶
  1. 1. 一、为什么调试能力很重要
  2. 2. 二、编译时保留调试信息
  3. 3. 三、GDB 基础
  4. 4. 四、Core Dump
  5. 5. 五、strace
  6. 6. 六、lsof 和文件句柄
  7. 7. 七、top、htop 和 ps
  8. 8. 八、perf 性能分析
  9. 9. 九、内存问题
  10. 10. 十、日志设计
  11. 11. 十一、线上排错流程
  12. 12. 十二、总结
请输入关键词进行搜索