Linux 程序要求内核为它们做一些事情。该strace
命令显示这些系统调用。您可以使用它们来了解程序如何工作以及为什么有时它们不工作。
内核和系统调用
尽管它们可能很聪明,但计算机程序不能为自己做所有事情。他们需要请求为他们执行某些功能。这些请求发送到 Linux 内核。通常,程序会调用一个库或其他软件接口,然后该库向内核发出适当的请求(称为系统调用)。
能够看到程序发出的系统调用和响应可以帮助您了解您感兴趣或您编写的程序的内部工作原理。这是 什么strace
呢。它可以帮助解决问题并寻找瓶颈。
这与使用类似工具调试应用程序不同gdb
。调试程序可让您在程序运行时调查程序的内部操作。它可以让您逐步执行程序的逻辑并检查内存和变量值。相比之下,strace
它的作用是在程序运行时捕获系统调用信息。当被跟踪的程序终止时,strace
将系统调用信息列出到终端窗口。
系统调用提供各种低级功能,例如对文件的读写操作、终止进程等。syscalls 手册页上有数百个系统调用的列表 。
安装 strace
如果strace
您的计算机上尚未安装,您可以非常轻松地安装它。
在 Ubuntu 上,使用以下命令:
sudo apt 安装 strace
在 Fedora 上,输入以下命令:
须藤 dnf 安装 strace
在 Manjaro 上,命令是:
须藤吃豆子-Sy strace
使用 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
我们可以清楚地看到write
系统调用将文本“Write this to the file”发送到我们打开的文件和exit_group
系统调用。这将终止应用程序中的所有线程并将返回值发送回外壳。
过滤输出
即使使用我们简单的演示程序,也有相当多的输出。我们可以使用-e
(expression) 选项。我们将传入我们想要查看的系统调用的名称。
strace -e 写./stex
您可以通过将多个系统调用添加为逗号分隔列表来报告多个系统调用。不要在系统调用列表中包含任何空格。
strace -e 关闭,写入 ./stex
将输出发送到文件
过滤输出的好处也是过滤输出的问题。你看到了你要求看到的东西,但你什么也看不到。并且一些其他输出可能比您要求查看的内容对您更有用。
有时,捕获所有内容并搜索和滚动整个结果集会更方便。这样,您就不会意外排除任何重要的内容。该-o
(输出)选项,可以从输出发送 strace
会话到一个文本文件中。
strace -o 跟踪输出.txt ./stex
然后,您可以使用该less
命令滚动列表并按名称搜索系统调用或其他任何内容。
少跟踪输出.txt
您现在可以使用所有less
的搜索功能来调查输出。
添加时间戳
您可以向输出添加多个不同的时间戳。的-r
(相对时间戳)选项添加时间戳,显示每个连续系统调用的开始之间的时间差。请注意,这些时间值将包括在前一个系统调用中花费的时间以及程序在下一个系统调用之前正在执行的任何其他操作。
strace -r ./stex
时间戳显示在每行输出的开头。
要查看每个系统调用所花费的时间,请使用-T
(syscall-times) 选项。这显示了在每个系统调用中花费的时间。
strace -T ./stex
持续时间显示在每个系统调用行的末尾。
要查看调用每个系统调用的时间,请使用-tt
(绝对时间戳)选项。这显示了“挂钟”时间,分辨率为微秒。
strace -tt ./stex
时间显示在每行的开头。
跟踪正在运行的进程
如果您要跟踪的进程已经在运行,您仍然可以附加strace
到它。为此,您需要知道进程 ID。您可以使用ps
with grep
来找到它。我们正在运行 Firefox。要找出的IDfirefox
过程中,我们可以使用ps
并把它管道grep
。
ps -e | 火狐
我们可以看到进程 ID 是 8483。我们将使用-p
(process ID) 选项来告诉strace
要附加到哪个进程。请注意,您需要使用sudo
:
须藤strace -p 8483
您将看到一条通知strace
已附加到该进程,然后系统跟踪调用将像往常一样显示在终端窗口中。
创建报告
的-c
(仅摘要)选项导致strace
打印报告。它会生成一个表,其中包含有关被跟踪程序进行的系统调用的信息。
strace -c ./stex
列是:
- % time:每个系统调用所花费的执行时间百分比。
- seconds:在每个系统调用中花费的总时间以秒和微秒表示。
- usecs/call:每个系统调用花费的平均时间(以微秒为单位)。
- 调用:每个系统调用被执行的次数。
- errors:每个系统调用的失败次数。
- syscall:系统调用的名称。
对于快速执行和终止的琐碎程序,这些值将显示零。对于比我们的演示应用程序执行更有意义的事情的程序,会显示实际值。
深入洞察,轻松
该strace
输出可以告诉你哪些系统调用正在作出,目前正在反复造的,又有多少执行时间被消耗内核端代码中。这是很好的信息。通常,当您试图了解代码内部发生的事情时,很容易忘记您的二进制文件几乎不间断地与内核交互以执行其许多功能。
通过使用 strace
,您可以看到完整的图片。
未经允许不得转载:表盘吧 » 如何使用 strace 监控 Linux 系统调用