程序中的系统调用工具(二十五):跟踪系统

优采云 发布时间: 2021-08-02 00:28

  程序中的系统调用工具(二十五):跟踪系统

  原文出处:

  原作者:Amit Kumar Sahaand Sayantini Ghosh

  翻译时间:2008 年 3 月 3 日

  译者:王旭

  译者注:翻译文章文章来改变你的心情,strace是一个有用的工具,LinuxGazette是一本不错的杂志,希望你喜欢这篇文章。

  了解一切如何运作很有趣。所有 C 程序员都知道在他们的 C 程序的“输入-处理-输出”循环中使用了许多系统调用。看到程序中使用了哪些系统调用,无疑是非常令人兴奋的。这篇文章就是关于这个话题的,让我们开始吧。

  什么是“strace”?

  'strace' 是一个用于跟踪进程在运行时进行的系统调用的工具。它还报告进程收到的信号(或软中断)。

  根据手册页,在最简单的情况下,“strace 运行指定的命令,直到命令完成。它拦截并记录进程收到的系统调用和信号。”

  直接在终端中输入“strace”命令来查看它的各种开关和选项:

  $ strace

usage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]

[-p pid] ... [-s strsize] [-u username] [-E var=val] ...

[command [arg ...]]

or: strace -c [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...

[command [arg ...]]

-c -- count time, calls, and errors for each syscall and report summary

[[[etc.]]]

  跟踪系统调用

  从一个简单的例子开始。考虑以下 C 代码(列表1):

  /* Listing 1*/

#include

int main()

{

return 0;

}

  假设编译后的目标文件名为‘temp.o’。运行如下:

  $strace ./temp.o

  您将获得以下跟踪结果输出:

  execve("./temp.o", ["./temp.o"], [/* 36 vars */]) = 0

brk(0) = 0x804a000

access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fba000

access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)

open("/etc/ld.so.cache", O_RDONLY) = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=68539, ...}) = 0

mmap2(NULL, 68539, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fa9000

close(3) = 0

access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3

read(3, "177ELF111331`100"..., 512) = 512

fstat64(3, {st_mode=S_IFREG|0644, st_size=1307104, ...}) = 0

mmap2(NULL, 1312164, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e68000

mmap2(0xb7fa3000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13b) = 0xb7fa3000

mmap2(0xb7fa6000, 9636, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fa6000

close(3) = 0

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e67000

set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e676c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0

mprotect(0xb7fa3000, 4096, PROT_READ) = 0

munmap(0xb7fa9000, 68539) = 0

exit_group(0) = ?

Process 8909 detached

  现在,让我们将理论与实践相结合。

  我们知道,当用户输入命令或可执行文件运行时,系统会创建一个“子”Shell,并使用这个子Shell来运行程序。这是通过系统调用“execve”实现的。因此,跟踪结果从以下内容开始:

  execve("./temp.o", ["./temp.o"], [/* 36 vars */]) = 0

  接下来,进程调用'brk()','open','access','open','close',直到最终进程从shell分离并使用“exit_group(0)”启动。

  如上,跟踪过程显示了系统调用及其返回值。

  strace 的信号报告功能

  我们来看看“strace”的信号上报功能。考虑以下 C 代码(列表2):

  /*Listing 2*/

#include

int main()

{

int i;

for(i=0;i>=0;i++)

printf("infinityn");

return 0;

}

  假设编译输出的可执行文件是“temp-1.o”。运行如下:

  $ strace -o trace.txt ./temp-1.o

  这里,“-o”开关会将跟踪结果保存到“trace.txt”文件中。

  在这里,您将看到“write()”系统调用将被连续调用。现在,使用“ctrl-c”结束进程

  现在,查看“trace.txt”

  $cat trace.txt

  最后几行应该是:

  --- SIGINT (Interrupt) @ 0 (0) ---

+++ killed by SIGINT +++

  因为我们使用"ctrl-c"结束进程,所以发送信号SIGINT给进程,就像"strace"的输出一样。

  采集与系统调用相关的统计数据

  使用“strace”,您还可以对跟踪的系统调用进行一些简单的统计。这是通过“-c”开关实现的。例如:

  $ strace -o trace-1.txt -c ./temp-1.o # 运行上述可执行程序 'temp-1.o'

$ cat trace-1.txt

% time seconds usecs/call calls errors syscall

------ ----------- ----------- --------- --------- ----------------

100.00 0.007518 0 46702 write

0.00 0.000000 0 1 read

0.00 0.000000 0 2 open

0.00 0.000000 0 2 close

0.00 0.000000 0 1 execve

0.00 0.000000 0 3 3 access

0.00 0.000000 0 1 brk

0.00 0.000000 0 1 munmap

0.00 0.000000 0 1 mprotect

0.00 0.000000 0 7 mmap2

0.00 0.000000 0 3 fstat64

0.00 0.000000 0 1 set_thread_area

------ ----------- ----------- --------- --------- ----------------

100.00 0.007518 46725 3 total

  如上,除了其他输出信息外,还输出了系统调用的统计信息,“write()”系统调用(总共运行了46702次),占用了进程的大部分时间 (100%)。

  后记

  本文简单介绍了“strace”的一些基本功能。该工具在搜索可执行程序中的错误和查找崩溃点时非常有用。使用“strace”可以大大减少可能出现问题的范围。

  与‘GNU Debugger’ (gdb) 和‘ltrace’一起,“strace”为 Linux 程序员提供了强大的调试功能。

  有用的链接:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线