如何使用 strace 监控 Linux 系统调用

4327c8d1faaf797

Linux 程序要求内核为它们做一些事情。该strace命令显示这些系统调用。您可以使用它们来了解程序如何工作以及为什么有时它们不工作。

内核和系统调用

尽管它们可能很聪明,但计算机程序不能为自己做所有事情。他们需要请求为他们执行某些功能。这些请求发送到 Linux 内核。通常,程序会调用一个库或其他软件接口,然后该库向内核发出适当的请求(称为系统调用)。

能够看到程序发出的系统调用和响应可以帮助您了解您感兴趣或您编写的程序的内部工作原理。这是 什么strace。它可以帮助解决问题并寻找瓶颈。

这与使用类似工具调试应用程序不同gdb。调试程序可让您在程序运行时调查程序的内部操作。它可以让您逐步执行程序的逻辑并检查内存和变量值。相比之下,strace它的作用是在程序运行时捕获系统调用信息。当被跟踪的程序终止时,strace将系统调用信息列出到终端窗口。

系统调用提供各种低级功能,例如对文件的读写操作、终止进程等。syscalls 手册页上有数百个系统调用的列表 。

安装 strace

如果strace您的计算机上尚未安装,您可以非常轻松地安装它。

在 Ubuntu 上,使用以下命令:

sudo apt 安装 strace

c4ca4238a0b9238

在 Fedora 上,输入以下命令:

须藤 dnf 安装 strace

eccbc87e4b5ce2f

在 Manjaro 上,命令是:

须藤吃豆子-Sy strace

c81e728d9d4c2f6

使用 strace 的第一步

我们将使用一个小程序来演示strace. 它没有做太多事情:它打开一个文件并向其中写入一行文本,并且没有任何错误检查。这只是一个快速的 hack 以便我们可以使用strace.

#include <stdio.h>

int main(int argc, char argv[]) { 

  // 文件句柄 
  文件 *fileGeek;

  // 打开一个名为“strace_demo.txt”的文件,或者创建它 
  fileGeek = fopen("strace_demo.txt", "w");

  // 向文件写入一些文本 
  fprintf(fileGeek, "将其写入文件");

  //关闭文件 
  fclose(fileGeek);

  //退出程序 
  返回 (0); 

} // 主线程结束

我们保存该到一个名为“文件io.c中”文件和编译它gcc转换成一种叫做可执行文件stex,命名为“ ST比赛充足的。”

gcc -o stex 文件-io.c

我们将strace从命令行调用并将我们的新可执行文件的名称作为我们想要跟踪的进程传递给它。我们可以轻松地跟踪任何 Linux 命令或任何其他二进制可执行文件。我们使用我们的小程序有两个原因。

第一个原因 strace是冗长。可以有很多输出。当你strace在愤怒中使用时这很好,但一开始可能会让人不知所措。strace我们的小程序输出有限。第二个原因是我们的程序功能有限,源代码简短直接。这使得更容易识别输出的哪些部分引用了程序内部工作的不同部分。

strace ./stex

a87ff679a2f3e71

我们可以清楚地看到write系统调用将文本“Write this to the file”发送到我们打开的文件和exit_group系统调用。这将终止应用程序中的所有线程并将返回值发送回外壳。

895a074a5b21632

过滤输出

即使使用我们简单的演示程序,也有相当多的输出。我们可以使用-e(expression) 选项。我们将传入我们想要查看的系统调用的名称。

strace -e 写./stex

e4da3b7fbbce234

您可以通过将多个系统调用添加为逗号分隔列表来报告多个系统调用。不要在系统调用列表中包含任何空格。

strace -e 关闭,写入 ./stex

1679091c5a880fa

将输出发送到文件

过滤输出的好处也是过滤输出的问题。你看到了你要求看到的东西,但你什么也看不到。并且一些其他输出可能比您要求查看的内容对您更有用。

有时,捕获所有内容并搜索和滚动整个结果集会更方便。这样,您就不会意外排除任何重要的内容。该-o(输出)选项,可以从输出发送 strace会话到一个文本文件中。

strace -o 跟踪输出.txt ./stex

8f14e45fceea167

然后,您可以使用该less 命令滚动列表并按名称搜索系统调用或其他任何内容。

少跟踪输出.txt

c9f0f895fb98ab9

您现在可以使用所有less的搜索功能来调查输出。

45c48cce2e2d7fb

添加时间戳

您可以向输出添加多个不同的时间戳。的-r(相对时间戳)选项添加时间戳,显示每个连续系统调用的开始之间的时间差。请注意,这些时间值将包括在前一个系统调用中花费的时间以及程序在下一个系统调用之前正在执行的任何其他操作。

strace -r ./stex

d3d9446802a4425

时间戳显示在每行输出的开头。

6512bd43d9caa6e

要查看每个系统调用所花费的时间,请使用-T(syscall-times) 选项。这显示了在每个系统调用中花费的时间。

strace -T ./stex

c20ad4d76fe9775

持续时间显示在每个系统调用行的末尾。

c51ce410c124a10

要查看调用每个系统调用的时间,请使用-tt(绝对时间戳)选项。这显示了“挂钟”时间,分辨率为微秒。

strace -tt ./stex

aab3238922bcc25

时间显示在每行的开头。

9bf31c7ff062936

跟踪正在运行的进程

如果您要跟踪的进程已经在运行,您仍然可以附加strace到它。为此,您需要知道进程 ID。您可以使用pswith grep来找到它。我们正在运行 Firefox。要找出的IDfirefox过程中,我们可以使用ps把它管道grep

ps -e | 火狐

c74d97b01eae257

我们可以看到进程 ID 是 8483。我们将使用-p(process ID) 选项来告诉strace要附加到哪个进程。请注意,您需要使用sudo

须藤strace -p 8483

70efdf2ec9b0860

您将看到一条通知strace已附加到该进程,然后系统跟踪调用将像往常一样显示在终端窗口中。

6f4922f45568161

创建报告

-c(仅摘要)选项导致strace打印报告。它会生成一个表,其中包含有关被跟踪程序进行的系统调用的信息。

strace -c ./stex

1f0e3dad9990834

列是:

  • % time:每个系统调用所花费的执行时间百分比。
  • seconds:在每个系统调用中花费的总时间以秒和微秒表示。
  • usecs/call:每个系统调用花费的平均时间(以微秒为单位)。
  • 调用:每个系统调用被执行的次数。
  • errors:每个系统调用的失败次数。
  • syscall:系统调用的名称。

对于快速执行和终止的琐碎程序,这些值将显示零。对于比我们的演示应用程序执行更有意义的事情的程序,会显示实际值。

深入洞察,轻松

strace输出可以告诉你哪些系统调用正在作出,目前正在反复造的,又有多少执行时间被消耗内核端代码中。这是很好的信息。通常,当您试图了解代码内部发生的事情时,很容易忘记您的二进制文件几乎不间断地与内核交互以执行其许多功能。

通过使用 strace,您可以看到完整的图片。

未经允许不得转载:表盘吧 » 如何使用 strace 监控 Linux 系统调用