strace命令+SystemTap脚本排查内存问题
strace 简介
strace 是 Linux 系统中的一个强大的命令行工具,用于跟踪和调试程序与内核之间的系统调用(system calls)和信号(signals)。它能帮助开发者和系统管理员诊断问题、调试程序行为以及分析性能瓶颈。
strace功能
通过 strace,可以看到正在执行的程序是如何与操作系统交互,比如:
- 跟踪系统调用:
- 执行了哪些系统调用(如 open()、read()、write() 等)。
- 系统调用的参数和返回值。
- 跟踪信号:
- 程序接收了哪些信号以及处理方式
- 诊断问题:
- 识别程序为何挂起、崩溃或性能不佳。
- 分析依赖:
- 查看程序对文件、网络、库等资源的访问情况。
strace用法
strace [选项] 命令 [命令参数]
strace [选项] 命令 [命令参数]
常用选项
-o <文件>:将输出写入指定文件,而不是标准输出。
-f:跟踪多线程或多进程程序中的所有子进程。
-p :附加到正在运行的进程(通过其 PID)。
-e trace=<类别>:仅跟踪指定类别的系统调用(如 file、network、process 等)。
-s <字节数>:设置字符串输出的最大长度(默认为 32 字节)。
-T:显示每个系统调用的耗时。
-tt:显示每个系统调用的时间戳(精确到微秒)。
-c:统计系统调用的次数和耗时。
排查内存问题思路
找到分配大小
strace -fp {PID} -e trace=mmap,munmap > mmap 2>&1
trace=mmap,munmap 表示只跟踪 mmap 和 munmap 系统调用。这两个调用分别用于:
mmap: 用于将文件或设备内存映射到进程的虚拟地址空间。
munmap: 用于解除文件或设备的内存映射。
通过这条命令:
- 跟踪正在运行的进程(PID),以及它的所有子进程(-f)。
- 专注于跟踪与内存映射相关的系统调用,只捕获 mmap 和 munmap。
- 将输出内容保存到文件 mmap 中,供后续分析。
mmap/munmap会存在返回地址,申请长度,线程号等信息,通过比对是否有固定长度的内存,只分配但是从释放。
假设发现存在4194304(4MB = 4 * 1024 * 1024)
SystemTap脚本
写一个 SystemTap 脚本(强大的动态跟踪工具,用于分析 Linux 系统内核和用户空间的行为; 许开发者编写脚本,定义探针(probe),在特定事件发生时收集信息或执行操作),动态跟踪和分析 Linux 内核或用户空间的行为。它通过定义一个探针(probe),在特定事件发生时执行指定的操作。
mmap.tap
probe syscall.mmap2 {if (length == 4194304) {printf("%d mmap\n", length);print_ubacktrace();}
}
- 定义了一个探针,绑定到 mmap2 系统调用。
- 当长度是4MB,打印一条日志信息以及对应的用户空间的调用栈,有助于定位是哪个函数或代码段发起了这个特定的 mmap2 调用。
运行上述脚本:
sudo stap -x <PID> mmap.tap
或者
sudo stap --ldd -d <BINARY> -x <PID> mmap.tap