shell学习五十四天----进程系统调用的追踪strace

strace

前言:strace常用来跟踪进程执行时的系统调用的所接受的信号.在linux世界,进程是不能直接访问硬件设备,当进程需要访问硬件(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备.strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间,有其在调试的时候,strace能帮助你追踪到一个程序所执行的系统调用.当你想知道程序和操作系统是如何交互的时候,这是极其方便的,比如你想知道执行了哪些系统调用,并且以何种顺序执行.

strace详解

格式:

strace [ -dffhiqrtttTvxx ] [ -acolumn ] [ -eexpr ] ... [ -ofile ] [-ppid ] ... [ -sstrsize ] [ -uusername ] [ -Evar=val ] ... [ -Evar ]... [ command [ arg ... ] ]

strace -c [ -eexpr ] ... [ -Ooverhead ] [ -Ssortby ] [ command [ arg... ] ]

选项:


选项名


说明


-f ,-F


告诉strace同时跟踪fork和vfork出来的信号


-o(字母)xxxx.txt


输出到某个文档


-e execve


只记录execve这类系统调用.

案例:

首先使用vim编写一个C语言的程序,代码如下:

#filename test.c

#include <stdio.h>

int main()

{

int a;

scanf(“%d”,&a);

printf(“%09d\n”,a);

return 0;

}

然后使用命令:#gcc -o test test.c,这样会得到一个可执行的文件.

我们执行这个可执行文件(先不使用strace):#./test

执行期间这个程序会要求我们输入一个整数,我们输入99,会得到以下结果:000000099

接着我们使用strace:#strace ./test

输出很多,我就不复制,我一看这个输出的是我想到了黑客帝国这部电影,我第一次看的时候差不多就是这样...当时觉得好炫酷,不过看见我自己电脑上的这一坨,你够了,我不想看到你!

输出的这一些内容称为strace的trace结构,从trace结构可以看到,系统首先调用execve开始一个新的进程,接着进行环境的初始化操作,最后停顿在”read(0,”上面,这就是执行到了我们的scanf函数,等待我们输入数字,在输入完99之后,在调用write函数将格式化后的数值”000000099”输出到屏幕上,最后掉用wxit_group退出进行,完成整个程序的执行过程.

跟踪信号传递.

我们还是使用上面那个编译好的test程序,来观察进程接收信号的情况.还是先:#strace ./test,等到等待输入的画面的时候不要输入任何东西,然后打开另一个窗口,输入如下命令:

#killall test

这个时候我们就能看到我们的test程序退出了,最后的trace结果的最后两行:

--- SIGTERM (Terminated) @ 0 (0) ---

+++ killed by SIGTERM +++

trace中很清楚的告诉你test进程”+++ killed by SIGTERM +++”,其中SIGTERM信号为程序结束信号,与SIGKILL不同的是该信号可以被阻塞和处理.通常用来要求程序自己正常退出.shell命令kill缺省产生SIGTERM.

系统调用统计

strace不光能追踪系统调用,通过使用-c选项,它还能江金城所有的系统调用做一个统计分析给你,案例如下:

#strace -c ./test(需要按下Ctrl+C)

% time     seconds  usecs/call     calls    errors syscall

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

-nan    0.000000           0         2           read

-nan    0.000000           0         1           write

-nan    0.000000           0         2           open

-nan    0.000000           0         2           close

-nan    0.000000           0         4           fstat

-nan    0.000000           0        10           mmap

-nan    0.000000           0         3           mprotect

-nan    0.000000           0         1           munmap

-nan    0.000000           0         1           brk

-nan    0.000000           0         1         1 access

-nan    0.000000           0         1           execve

-nan    0.000000           0         1           arch_prctl

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

100.00    0.000000                    29         1 total

-c选项的含义是统计每一系统调用的所执行的时间,次数和出错的次数等.

常用参数说明

除了-c参数之外,strace还提供了其他有用的参数给我们,让我们方便的得到自己想要的信息,介绍如下:

重定向输出:

参数-o用在将strace的结果输出到文件中,如果不指定-o参数的话,默认的输出设备是STDERR,也就是说使用”-o filename”和”2>filename”的结果是一样的.

以下这两个命令都是讲strace结果输出到文件test.txt中

#strace -c -o test.txt ./test

#strace -c ./test 2>test.txt

对系统调用进行计时

strace可以使用参数-T将每个系统调用所花费的事件打印出来,每个掉用的时间花销现在在调用行最右边的尖括号里面.

read(0, 1

"1\n", 1024)                    = 2 <7.195016>

fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 <0.000010>

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1431bd1000 <0.000014>

write(1, "000000001\n", 10000000001

)             = 10 <0.000011>

exit_group(0)                           = ?

表示看不懂,不懂得东西,现在不要深究.

系统调用的时间

这是一个很有用的功能,strace会将每次系统调用的发生时间记录下来,只要使用-t/tt/ttt三个参数就可以看到效果了,具体案例如下:


参数名


输出样式


说明


-t


10:50:10 exit_group(0)


输出结果精确到秒


-tt


10:50:48.463555 exit_group(0)


输出结果精确到微秒


-ttt


1438138307.923671 exit_group(0)


精确到微妙,而且时间表示为unix时间戳

截断输出

-s参数用于指定trsce结果的每一行输出的字符串的长度,下面看看test程序中-s参数对结果有什么影响,现指定-s为10,然后在read的地方输入一个超过10个字符的字符串:

#strace -s 10 ./test

read(0, 123456789011

"1234567890"..., 1024)          = 13

部分输出结果

分析:我们一共输入了12个字符,而我们看到的结果只有10个

trace一个现有的进程

strace不光能自己初始化一个进程进行trace,还能追踪现有的进程,参数-p就是去的这个用法,用法简单,具体如下:

#strace -p pid   //跟踪指定的进程PID

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 21:08:39

shell学习五十四天----进程系统调用的追踪strace的相关文章

shell学习五十天----查看进程ps命令

进程列表 列出进程中最重要的命令便是进程状态命令:ps. ps命令是进程状态(Process Status)的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信息,就可以使用top命令. 要对进程进行检测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而ps命令就是最基本同时也是非常强大的进程查看命令.使用该命令可以确定有哪些进程正在运行和运行的状态,进程是否结束,进程有没有僵尸,哪些进

学习五十四

十四周四次课(5月14日)16.1 Tomcat介绍16.2 安装jdk16.3 安装Tomcat 扩展java容器比较 http://my.oschina.net/diedai/blog/271367 http://www.360doc.com/content/11/0618/21/16915_127901371.shtmlj2ee.j2se.ejb.javabean.serverlet.jsp之间关系 http://bbs.csdn.net/topics/50015576tomcat ser

shell学习五十六天----延迟进程调度

延迟进程调度 前言:大部分时候,我们都希望进程快点開始,开点结束,别卡.而shell的运行,也是在前一个命令后,立即接着运行下一个命令.命令完毕的速度是与资源的限制有关,且不在shell的权限下. 在交谈模式中使用下,有时不必等到命令完毕才干运行还有一个.这是shell提供的一个简单方式:全部的命令仅仅要在最后加上&字符,都可起始于后台运行,无需等待.仅仅有在少数情况下,必须等待后台进程完毕. 稍稍有四种情况须要延时进程事实上,知道未来的某个事件才运行. 第一种 sleep sleep命令经常使

shell学习三十四天----printf详解

printf 先来看一个简单的例子:使用命令printf "hello,world\n", 输出:hello,world 再使用echo "hello,world\n",输出为:hello,world\n 案例二:使用命令printf "%s\n" hello,world 输出结果为:hello,world printf命令的完整语法有两个部分: printg format-string [arguments] 第一部分为描述格式规格的字符串,他

“全栈2019”Java第五十四章:多态详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第五十四章:多态详解 下一章 "全栈2019"Java第五十五章:方法的静态绑定与动态绑定 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组"

JavaScript学习总结(十四)——JavaScript编写类的扩展方法

在?J?a?v?a?S?c?r?i?p?t?中?可以使?用?类的p?r?o?t?o?t?y?p?e属性来?扩?展?类的属?性?和?方?法,在实际开发当中,当JavaScript内置的那些类所提供的动态方法和动态属性不满足我们实际开发时,我们就可以通过"prototype"属性给自定义类添加方法和属性或者扩展原有的类中的方法和属性. 一.扩展JavaScript内置类,添加动态方法 语法格式: 类名.prototype.方法名 = function([param1],[param2],.

QT开发(五十四)———QML组件

QT开发(五十四)---QML组件 QML组件是由基本元素组合成的一个复杂的可重用的组合元素.QML 提供了多种方法来创建组件. 基于文件的组件将QML元素放置在一个单独的文件中,然后给文件一个名字,可以通过名字来使用组件.如果有一个文件名为Cell.qml,就可以在QML中使用Cell { - }形式.自定义组件的文件名的首字母必须大写. Cell.qml文件: import QtQuick 2.0   Item {     id: container     property alias c

shell编程(十四)--- until循环

until循环语法格式: until CONDITION do     statement done 说明: until进入循环的条件是:condition不成立时,就执行循环. until进入循环的条件正好和while相反,while进入循环的条件是:condition成立时,就进入循环. 示例1:while循环 [[email protected] Learn]# cat while.sh  #!/bin/bash declare -i sum=0 declare -i i=0 while 

第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection)

第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲-数据收集(Stats Collection) Scrapy提供了方便的收集数据的机制.数据以key/value方式存储,值大多是计数值. 该机制叫做数据收集器(Stats Collector),可以通过 Crawler API 的属性 stats 来使用无论数据收集(stats collection)开启或者关闭,数据收集器永远都是可用的. 因此您可以import进自己的模块并使用其API(增加值或者设置新的状态键(stat k