应该如何使用strace?

一位同事曾经告诉我,当Linux上所有的东西都debugging失败的时候,最后一个select是使用strace 。

我试图学习这个奇怪的工具背后的科学,但我不是一个系统pipe理员大师,我真的没有得到的结果。

所以,

  • 这究竟是什么,它是做什么的?
  • 应该如何以及在何种情况下使用?
  • 应如何理解和处理输出?

简言之,这个东西是如何工作的?

Strace概述
strace可以被看作是一个轻量级的debugging器。 它允许程序员/用户快速找出程序如何与操作系统进行交互。 它通过监视系统调用和信号来做到这一点。

用途
当你没有源代码或者不想被打扰的时候很好。
另外,如果你不喜欢打开GDB,但是只对理解外部交互感兴趣,那么对你自己的代码有用。

一个很好的介绍
我碰到了这个介绍,就是在前几天使用: strace hello world

简而言之,strace跟踪程序发出的所有系统调用及其返回代码。 考虑诸如文件/套接字操作之类的东西,还有更多的晦涩之处。

如果你有一些C的工作知识,这是最有用的,因为这里系统调用将更准确地代表标准的C库调用。

假设你的程序是/ usr / local / bin / cough。 只需使用:

 strace /usr/local/bin/cough <any required argument for cough here> 

要么

 strace -o <out_file> /usr/local/bin/cough <any required argument for cough here> 

写入'out_file'。

所有的strace输出将会发送到stderr(注意,它的绝对容量通常要求redirect到一个文件)。 在最简单的情况下,你的程序将中止一个错误,你将能够看到它在strace输出中与操作系统的最后一次交互。

更多的信息应该可用于:

 man strace 

strace列出了所应用的进程完成的所有系统调用 。 如果你不知道系统调用是什么意思,你将无法获得更多的里程。

不过,如果你的问题涉及到文件或path或环境值,在有问题的程序上运行strace并将输出redirect到一个文件,然后为你的path/文件/ envstring查找该文件可能会帮助你看到你的程序实际上试图做,与你预期的不同。

Strace脱颖而出,作为调查生产系统的一个工具,你无法在debugging器下运行这些程序。 特别是,我们在以下两种情况下使用了strace:

  • 程序foo似乎处于僵局,并已变得没有反应。 这可能是gdb的目标; 然而,我们并不总是有源代码,或者有时候处理脚本语言,这些脚本语言不是直接在debugging器下运行的。 在这种情况下,你在一个已经运行的程序上运行strace,你将得到系统调用的列表。 如果您正在研究客户端/服务器应用程序或与数据库交互的应用程序,这一点特别有用
  • 调查一个程序为什么很慢。 特别是我们刚刚搬到了新的分布式文件系统,系统的新吞吐量非常缓慢。 你可以用'-T'选项来指定strace,它会告诉你在每个系统调用中花了多less时间。 这有助于确定文件系统为什么会导致速度放慢。

有关使用strace进行分析的示例,请参阅我对此问题的回答 。

我一直使用strace来debugging权限问题。 技术是这样的:

 $ strace -e trace=open,stat,read,write gnome-calculator 

gnome-calculator是你想运行的命令。

strace -tfp PID将监视PID进程的系统调用,因此我们可以debugging/监视我们的进程/程序状态。

Strace可以用作debugging工具,也可以用作原始分析器。

作为一个debugging器,你可以看到如何调用系统调用,执行和返回。 这是非常重要的,因为它可以让你不仅看到一个程序失败,但为什么一个程序失败。 通常这只是由于糟糕的编码没有捕捉到程序的所有可能的结果。 其他时间只是文件的硬编码path。 没有一丝不苟,你可以猜测出什么地方出了问题。 用strace你会得到一个系统调用细分,通常只是看一个返回值告诉你很多。

分析是另一个用途。 您可以使用它来单独执行每个系统调用,或者作为一个聚合来执行。 虽然这可能不足以解决您的问题,但至less会大大缩小潜在的嫌疑犯名单。 如果你在单个文件中看到很多的fopen / close对,那么你可能不会在循环的每个执行过程中打开和closures文件,而不是在循环之外打开和closures文件。

Ltrace是strace的亲戚,也非常有用。 你必须学会​​分辨你的瓶颈在哪里。 如果总执行时间是8秒,而你在系统调用上只花费0.05秒,那么对程序进行分层并不会对你有什么好处,问题出在你的代码中,这通常是一个逻辑问题,或者程序实际上需要采取那么长时间运行。

strace / ltrace最大的问题是读取输出。 如果你不知道如何进行调用,或者至less是系统调用/函数的名字,那么就很难说明这些意思了。 了解函数返回的内容也是非常有益的,特别是对于不同的错误代码。 虽然这是一个痛苦的决定,但他们有时真的回到知识的明珠; 一旦我看到一个情况,我用尽了inodes,但没有空闲的空间,因此所有常用的工具没有给我任何警告,我只是不能创build一个新的文件。 从strace的输出中读取错误代码指向正确的方向。

strace是学习程序如何进行各种系统调用(对内核的请求)的一个很好的工具,并且还报告那些失败的错误值以及与失败相关的错误值。 并非所有的失败都是错误。 例如,试图search文件的代码可能会得到一个ENOENT(没有这样的文件或目录)错误,但是这在代码的逻辑中可能是可以接受的。

使用strace的一个很好的用例是在临时文件创build期间debugging竞态条件。 例如,一个可能通过将进程ID(PID)附加到某个预定义的string来创build文件的程序在multithreading场景中可能会遇到问题。 [PID + TID(进程ID +线程ID)或更好的系统调用,如mkstemp将解决此问题]。

这对debugging崩溃也很好。 你可能会发现这个(我的)文章strace和debugging崩溃有用。

Strace是一个工具,可以告诉您应用程序如何与您的操作系统进行交互。

它通过告诉你你的应用程序使用什么操作系统调用以及调用它们的参数来实现这一点。

因此,例如,您会看到您的程序尝试打开哪些文件,并使通话成功。

您可以使用此工具debugging各种问题。 例如,如果应用程序说它找不到你知道你已经安装的库,strace会告诉你应用程序在哪里查找这个文件。

这只是冰山一angular。