题
一位同事曾经告诉我,最后一个选项的时候一切都已失败的调试在Linux上使用 strace.
我试着了解背后的科学的这个奇怪的工具,但我不是一个系统的管理大师,我并没有真正取得结果。
所以,
- 究竟是什么和是什么呢?
- 如何和在哪些情况下应使用?
- 如何应的输出可以理解和处理?
在简短的, 在简单的话, 怎么会这些东西的工作?
解决方案
Strace概述
strace可以被看作是一个重量轻,调试器。它允许一名程序员/用户迅速找出一个程序是相互作用的操作系统。它通过监测系统的电话和信号。
使用
好的,当你没有的源代码或不想被打扰,真正通过它。
此外,有用于自己的代码如果你不喜欢开放库,但是只有兴趣了解外部的相互作用。
一个好一点的介绍
我遇到了这个介绍strace只使用其他天: strace世界你好
其他提示
简单地说,strace痕迹的所有系统的呼吁发出一个程序随着他们的返回代码。认为东西,如文件/socket操作和更多的模糊的。
它是最有用的,如果你有一些工作知识的C这里的系统调将更准确地确立标准C图书馆的电话。
让我们说说你的程序是/usr/local/bin/咳嗽。只是使用:
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(请注意,数量庞大,它常常要求重定向到文件)。在最简单的情况下,程序将中止与一个错误,你就可能看到什么在其最后一次相互作用的操作系统在strace输出。
更多的信息应当提供:
man strace
strace列出了所有 系统调用 通过这个过程中,它的应用。如果你不知道什么系统通话的意思是,你不能得到多少里程数。
尽管如此,如果问题涉及文件或路径或环境价值观,运行strace上有问题的程序和重新定向输出到文件然后grepping该文件对你的路径/文件/env串可以帮助你看见什么你的计划是 实际上 试图这样做,因为不同的是你预期的那样。
Strace脱颖而出,成为一个工具,用于调查的生产系统在那里你可买不起这些程序的下一个调试器。特别是,我们已经用strace在以下两种情况:
- 程序foo似乎是在僵局,已成为反应迟钝。这可能是一个目标库;然而,我们没有始终得源代码或有时是处理与编写脚本语言,不是直接的下运行的一个调试器。在这种情况下,运行strace在一个已经在运行的程序和你会得到清单的电话系统正在取得进展。这是特别有用的,如果你正在调查一个客户/服务器应用程序或一种应用程序进行交互数据库
- 调查为什么一个程序是缓慢的。特别是,我们刚刚搬到一个新的分布式文件系统和新系统的吞吐量是非常缓慢。你可以指定strace与'-T'的选项,它会告诉你怎么花了很多时间在每一个系统的呼吁。这有助于确定为什么该文件系统造成的事情要慢下来。
例分析使用strace看到我的回答 这个问题.
我用strace所有的时间去调试的权限问题。该技术是这样的:
$ strace -e trace=open,stat,read,write gnome-calculator
哪里 gnome-calculator
是命令,你要运行。
strace-tfp PID将监测PID进程的系统电话,因此我们可以试/监测我们的进程/程序的状态。
Strace可以作为一个调试工具,或作为原始分析器。
作为一个调试器,你可以看到如何给定系统的电话被称为执行和什么他们返回。这是非常重要,因为它允许你看到的不仅是程序失败了,但为什么一个计划失败了。通常它只是一个糟糕的结果的编码不能捕捉所有的可能结果的程序。其他时候,它只是硬编码的途径的文件。没有strace你猜到了什么差错在哪里和如何。与strace你会得到一个崩溃的一个系统调用,通常只是在寻找返回值告诉你很多。
分析是另一个使用。你可以用它来的时间执行的各个系统调用单独地、或者作为一个集合体。虽然这可能不足以解决你的问题,它将至少大大缩小该列表的潜在嫌疑人。如果你看到很多fopen/关闭对于一个单一的文件,你可能unnecessairly打开和关闭文件的每一执行的一个循环,而不是打开并且关闭它之外的一环。
Ltrace是strace近的表妹,也非常有用的。你必须学会分辨哪里你的瓶颈。如果总的执行有8秒钟,你只花0.05秒系统电话,然后stracing的程序是不会对你有多好,问题是在你的代码,这通常是一个逻辑问题,或该程序实际上需要花这么长时间来运行。
最大的问题strace/ltrace是阅读他们的输出。如果你不知道如何调用,或者至少在名称的系统调用/职能,这将是很难破译的意思。知道什么是功能的返回,也可以是非常有益的,尤其是对于不同的错误代码。虽然这是一个痛苦的破译,他们有时候真的返回珍珠的知识;一旦我看到一个情况下,我跑出来的节点,而不是出了自由空间,因此所有平常的事业没有给我任何警告,我只是不能让一个新的文件。阅读的错误代码从strace的输出指出我在正确的方向。
Strace是一个工具,告诉你如何应用程序进行交互用操作系统。
它告诉你什么操作系统电话系统应用程序使用了什么参数,它呼吁它们。
因此,举例来说你看到什么文件的程序试图开放和天气话成功。
你可以试各种各样的问题与这种工具。例如,如果应用说,它无法找到图书馆,你知道你已经安装了你strace会告诉你这里的应用程序是在寻找的文件。
和这只是冰山的一角。
strace是一个很好的工具,用于学习如何计划使得各种系统的电话(请求的核心),也报告的失败的错误的价值相关联的失败。不是所有的失败的错误。例如,一个代码,试图寻找一个文件可以得到一个ENOENT(没有这种文件的目录或)错误,但这可能是一个可接受的方案在逻辑的代码。
一个好用的情况下使用strace是调试的竞争条件在临时文件的创建。例如一个程序,可以创建文件的通过追加的进程ID(PID)一些predecided串可能会面临的问题在多线程的情况。[PID+TID(process id+thread id)或一个更好的系统调如mkstemp将解决这个问题].
这也是进行调试的崩溃。你可以找到 这个(我)条strace和调试崩溃 有用的。
我喜欢一些问题的答案在那里读 strace
检查你与你的操作系统。
这正是我们可以看到。系统调用。如果你比较 strace
和 ltrace
差异更为明显。
$>strace -c cd
Desktop Documents Downloads examples.desktop Music Pictures Public Templates Videos
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 7 read
0.00 0.000000 0 1 write
0.00 0.000000 0 11 close
0.00 0.000000 0 10 fstat
0.00 0.000000 0 17 mmap
0.00 0.000000 0 12 mprotect
0.00 0.000000 0 1 munmap
0.00 0.000000 0 3 brk
0.00 0.000000 0 2 rt_sigaction
0.00 0.000000 0 1 rt_sigprocmask
0.00 0.000000 0 2 ioctl
0.00 0.000000 0 8 8 access
0.00 0.000000 0 1 execve
0.00 0.000000 0 2 getdents
0.00 0.000000 0 2 2 statfs
0.00 0.000000 0 1 arch_prctl
0.00 0.000000 0 1 set_tid_address
0.00 0.000000 0 9 openat
0.00 0.000000 0 1 set_robust_list
0.00 0.000000 0 1 prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 93 10 total
另一方面,有的是 ltrace
跟踪功能。
$>ltrace -c cd
Desktop Documents Downloads examples.desktop Music Pictures Public Templates Videos
% time seconds usecs/call calls function
------ ----------- ----------- --------- --------------------
15.52 0.004946 329 15 memcpy
13.34 0.004249 94 45 __ctype_get_mb_cur_max
12.87 0.004099 2049 2 fclose
12.12 0.003861 83 46 strlen
10.96 0.003491 109 32 __errno_location
10.37 0.003303 117 28 readdir
8.41 0.002679 133 20 strcoll
5.62 0.001791 111 16 __overflow
3.24 0.001032 114 9 fwrite_unlocked
1.26 0.000400 100 4 __freading
1.17 0.000372 41 9 getenv
0.70 0.000222 111 2 fflush
0.67 0.000214 107 2 __fpending
0.64 0.000203 101 2 fileno
0.62 0.000196 196 1 closedir
0.43 0.000138 138 1 setlocale
0.36 0.000114 114 1 _setjmp
0.31 0.000098 98 1 realloc
0.25 0.000080 80 1 bindtextdomain
0.21 0.000068 68 1 opendir
0.19 0.000062 62 1 strrchr
0.18 0.000056 56 1 isatty
0.16 0.000051 51 1 ioctl
0.15 0.000047 47 1 getopt_long
0.14 0.000045 45 1 textdomain
0.13 0.000042 42 1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00 0.031859 244 total
虽然我检查了手册若干时,我还没有找到名字的由来 strace
但这是有可能的系统的跟踪,因为这是显而易见的。
有三个更大的注意要说的 strace
.
注1:这两个职能 strace
和 ltrace
正在使用该系统通话 ptrace
.所以 ptrace
系统调用有效如何 strace
工程。
该ptrace()系统通话提供了一种手段,通过这一过程中(该 "追踪器")可以观察和控制执行的另一个进程 (该"特蕾西"),以及审查和改变特蕾西的记忆力和 寄存器。它主要用于实现断点调试 和系统通话跟踪。
注2:有不同的参数可用 strace
, ,由于 strace
可以非常详细。我喜欢尝试 -c
这就像是一个摘要的事情。基于上 -c
你可以选择的一个系统-电话喜欢 -e trace=open
在那里你将只能看到这一呼吁。这可有趣的,如果你是研究的文件将打开在命令你们追踪。当然,你可以使用 grep
为同一目的,但是注意需要重定向这样的 2>&1 | grep etc
明白,配置文件时引用该命令发出的。
注3:我找到这一非常重要的注意。你是不是限于一个具体的建筑。 strace
将吹你的头脑,因为它可以跟踪过来的二进制文件的不同的架构。
最小的运行实例
如果一个概念不清楚,没有一个简单的例子,你没看见,解释它。
在这种情况下,例是Linux x86_64会的独立(不libc)你好世界:
你好。S
.text
.global _start
_start:
/* write */
mov $1, %rax /* syscall number */
mov $1, %rdi /* stdout */
mov $msg, %rsi /* buffer */
mov $len, %rdx /* buffer len */
syscall
/* exit */
mov $60, %rax /* exit status */
mov $0, %rdi /* syscall number */
syscall
msg:
.ascii "hello\n"
len = . - msg
上游。.
组装和运行:
as -o hello.o hello.S
ld -o hello.out hello.o
./hello.out
产出的预期:
hello
现在让我们使用strace在,例如:
env -i ASDF=qwer strace -o strace.log -s999 -v ./hello.out arg0 arg1
cat strace.log
我们使用:
env -i ASDF=qwer
控制环境的变量: https://unix.stackexchange.com/questions/48994/how-to-run-a-program-in-a-clean-environment-in-bash-s999 -v
以显示更全面的信息记录
strace.log
现在包含:
execve("./hello.out", ["./hello.out", "arg0", "arg1"], ["ASDF=qwer"]) = 0
write(1, "hello\n", 6) = 6
exit(0) = ?
+++ exited with 0 +++
这样一个小例,每一个字符的输出是不言而喻:
execve
行:演示如何strace
执行hello.out
, 包括CLI参数和环境记录man execve
write
行:表示写信系统电话,我们作出。6
是的长串"hello\n"
.= 6
是的返回值系统的呼吁,其作为记录在案man 2 write
是字节的数量编写的。exit
行:显示出系统的呼吁,我们已经作出。没有返回值,因为该方案退出!
更复杂的例子
该应用程序的strace当然是看到其系统调复杂的程序实际上这样做,以帮助调试和优化程序。
值得注意的是,大多数系统电话,你很可能会遇到在Linux有glibc包装, 他们中的许多人从POSIX.
在内部,glibc包装使用内联会或多或少是这样的: 如何调用一个系统调通过sysenter在内联会?
下一个例子你应该研究是一个POSIX write
你好世界:
主。c
#define _XOPEN_SOURCE 700
#include <unistd.h>
int main(void) {
char *msg = "hello\n";
write(1, msg, 6);
return 0;
}
汇编和运行:
gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out
这个时候,你会看到一堆的电话系统正在作出glibc之前 main
建立一个良好的环境为主。
这是因为我们现在不使用一个独立的程序,而是一个更常见的glibc程序,它允许对libc的功能。
然后,在每一端, strace.log
包含:
write(1, "hello\n", 6) = 6
exit_group(0) = ?
+++ exited with 0 +++
所以我们得出的结论, write
POSIX功能的用途,惊喜!, Linux write
系统调用。
我们还观察到, return 0
导致一个 exit_group
呼叫,而不是的 exit
.哈,我不知道这个!这就是为什么 strace
是很爽。 man exit_group
然后说:
这个系统调用相当于出口(2)除外,它将终止,不仅调线,但所有程呼吁进程的线组。
这里是另一个例子,在那里我学习系统通话 dlopen
使用: https://unix.stackexchange.com/questions/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710
测试Ubuntu的16.04,海湾合作委员会6.4.0所,Linux内核4.4.0.