0.引言

当程序莫名卡死、崩溃或报出令人费解的错误时,我们常用的“加日志、盲目猜测、反复重启”等笨办法往往无效。此时,真正的症结通常隐藏在我们看不见的地方:程序与操作系统内核的边界。

在各种诡异的问题面前,strace往往能给我们不一样的表现。strace 不是什么复杂的工具linux安装,却能解决 90% 以上的 Linux 程序运行时问题。它的核心作用很简单:追踪程序与内核之间的所有系统调用,把程序“背后做的事”全部暴露在阳光下。无论是文件读写、网络连接,还是权限验证、信号处理linux系统错误日志,只要程序调用了内核提供的服务,strace 就能捕捉到完整细节,帮我们快速定位问题根源。

本文不堆砌复杂的内核原理,只聚焦“实战”——从 strace 基础用法入手,手把手教你如何用它追踪系统调用、分析异常日志,最终搞定工作中常见的疑难 BUG,让你看完就能直接上手使用。

1.strace能帮我们做什么

1.1 系统调用是什么

简单来说,系统调用是用户态程序请求操作系统内核为其服务的唯一正式接口。几乎所有涉及 外部资源 的操作,最终都通过系统调用来完成:

因此linux系统错误日志,通过观察系统调用,你就能知道程序实际上做了什么,而不是猜测它做什么。

1.2 strace的作用

strace排查Linux程序问题_linux系统错误日志_strace系统调用追踪

简单来说linux mint,strace 的核心价值是“穿透程序黑盒”。我们写的代码(无论是 C、Python 还是 Go),最终都要通过“系统调用”(system call)向 Linux 内核请求服务,比如:

程序运行出错,很多时候是因为系统调用返回了错误(比如 open() 返回 -1,表示文件打开失败)。而 strace 能实时捕捉到这些系统调用的“输入参数”“返回值”“执行耗时”,甚至能看到程序收到的信号(比如 kill 信号导致程序闪退)。

2.基础用法和参数介绍

2.1 基础语法

使用它启动程序:

strace [选项] 命令 [命令参数]

附加到进程:

strace -p PID

2.2 常用参数介绍

选项

说明

-c

统计系统调用次数和时间

-f

跟踪子进程

-e trace=系统调用

只跟踪特定系统调用

-o 文件

将输出写入文件

-p PID

附加到正在运行的进程

-t

显示时间戳

-T

显示系统调用耗时

-s 大小

strace排查Linux程序问题_linux系统错误日志_strace系统调用追踪

设置字符串最大显示长度(默认32)

-v

显示更详细的信息

3.场景实例

比如我们有如下代码,要记录一些错误到日志中,但是发现并没有记录也并没有输出到标准输出,此场景和文件的open,close等有关:

#include 
#include 
#include 
#include 
std::string logpath;
void recordLog(std::string& s)
{
    struct stat buf;
    if(stat(logpath.c_str(), &buf) != 0)
    {
        // 打开文件,将标准输出重定向到 output.txt
        freopen(logpath.c_str(), "a+", stdout);
    }
    std::cout<<s<<std::endl;
}
int main() {
    
    if(1) //假设出现了一些错误,需要记录
    {
        std::string s = "some error";
        recordLog(s);
    }
   
    logpath = "log.txt";
    
    //中间逻辑
    
    // 关闭文件(标准输出会恢复吗?不会,除非重新设置)
    //fclose(stdout);
    
    return 0;
}

此时我们可以使用strace来跟踪:

strace -e trace=open,dup2,close,openat ./a.out

strace系统调用追踪_linux系统错误日志_strace排查Linux程序问题

linux系统错误日志_strace系统调用追踪_strace排查Linux程序问题

图中可以看到我们openat了一个空路径,且关闭了fd 1,我们就可以进一步跟踪其在那关闭的。gdb启动程序后断点看是哪里的调用关闭的。

gdb a.out
b close if $rdi==1 //第一个参数$rdi,和机器有关系
bt  查看堆栈

strace排查Linux程序问题_linux系统错误日志_strace系统调用追踪

我们就能判断是何处的调用导致的问题了,我们这个例子是缺少路径判断以及freopen的错误处理。

4.使用总结

其实 strace 并不复杂,它的核心逻辑就是“追踪系统调用,定位错误根源”,总结起来就是3个核心心法:

linux系统错误日志_strace系统调用追踪_strace排查Linux程序问题

1)先定位场景:根据问题现象(权限、文件、网络、闪退),确定要追踪的系统调用类型(file、network 等);

2)再过滤信息:用 -e、-c 等选项过滤无用日志,聚焦错误记录或耗时记录;

3)最后看细节:重点关注系统调用的“参数”“返回值”“错误原因”,结合问题现象推导解决方案。

strace 就像 Linux 程序排查问题的“显微镜”,它能帮我们看到程序“背后的操作”,让原本无从下手的疑难 BUG 变得清晰可见。

建议你现在就打开 Linux 终端,试着用 strace 追踪一个简单的命令(比如 ls、curl),熟悉它的输出格式,再结合本文的实战场景,动手排查一个自己遇到的问题——只有实操,才能真正掌握这个强大的工具。

Tagged:
Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复