关于strace

简单说,strace是可以跟踪一个程序在做什么的命令。

一 它可以监控某个要执行的命令,比如平时最常见的ls命令:

[root@localhost a]# strace ls
execve("/bin/ls", ["ls"], [/* 26 vars */]) = 0
brk(0)                                  = 0x11a8000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4792b00000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=63053, ...}) = 0
mmap(NULL, 63053, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4792af0000
close(3)                                = 0
open("/lib64/libselinux.so.1", O_RDONLY) = 3
....



由上面可以看出,打开的是那个文件,还有依赖的文件

二 也可以监控正在执行的命令,比如nginx

[root@localhost a]# ps aux|grep nginx
root      1496  0.0  0.0 127536  1564 ?        Ss   Sep18   0:00 nginx: master process /Data/apps/nginx/sbin/nginx
daemon    1499  2.2  0.2 162008 36640 ?        S    Sep18 128:43 nginx: worker process      
...
[root@localhost a]# strace -p 1499
Process 1499 attached - interrupt to quit
epoll_wait(25, {{EPOLLIN|EPOLLOUT, {u32=3002737265, u64=140018936586865}}}, 512, 141) = 1
recvfrom(1067, "", 16384, 0, NULL, NULL) = 0
close(1067)                             = 0
epoll_wait(25, {{EPOLLIN|EPOLLOUT, {u32=3002704696, u64=140018936554296}}}, 512, 138) = 1
recvfrom(812, "\1\6\0\1\3v\2\0X-Powered-By: PHP/5.2.13"..., 4096, 0, NULL, NULL) = 4096
readv(812, [{".aslibra.com/\" target=\"_blank"..., 4096}], 1) = 4096
...



由上面可以看出,nginx在从后端的php接收数据

三 用strace细节可以做什么呢?

1 监测程序做什么: strace 命令
2 监测某个进程:strace -p pid
3 参数,man strace可以获知每个参数说明,说一些常用的:
监测每个步骤花了多少时间: -t 秒 -tt 毫秒 -ttt 时间戳
统计每个操作类型的用时 -c
只列举指定的操作 -e,比如 -e open,只列出打开文件的操作
输出到文件 -o filename
记录相对时间 -r

四 操作实例

1 检查程序引用的配置文件和打开的依赖文件,以nginx为例

[root@pic ~]# strace -e open /Data/apps/nginx/sbin/nginx -t
#加载依赖的库文件
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/libcrypt.so.1", O_RDONLY)    = 3
open("/lib/libpcre.so.0", O_RDONLY)     = 3
open("/lib/libcrypto.so.4", O_RDONLY)   = 3
open("/usr/lib/libz.so.1", O_RDONLY)    = 3
open("/lib/tls/libc.so.6", O_RDONLY)    = 3
open("/usr/lib/libgssapi_krb5.so.2", O_RDONLY) = 3
open("/usr/lib/libkrb5.so.3", O_RDONLY) = 3
open("/lib/libcom_err.so.2", O_RDONLY)  = 3
open("/usr/lib/libk5crypto.so.3", O_RDONLY) = 3
open("/lib/libresolv.so.2", O_RDONLY)   = 3
open("/lib/libdl.so.2", O_RDONLY)       = 3
open("/etc/localtime", O_RDONLY)        = 3
#加载配置文件和检查系统配置文件
open("/Data/apps/nginx/logs/error.log", O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE, 0644) = 3
open("/Data/apps/nginx/conf/nginx.conf", O_RDONLY|O_LARGEFILE) = 4
open("/etc/nsswitch.conf", O_RDONLY)    = 5
open("/etc/ld.so.cache", O_RDONLY)      = 5
open("/lib/libnss_files.so.2", O_RDONLY) = 5
open("/etc/passwd", O_RDONLY)           = 5
open("/etc/group", O_RDONLY)            = 5
open("/Data/apps/nginx/conf/mime.types", O_RDONLY|O_LARGEFILE) = 5
open("/etc/resolv.conf", O_RDONLY)      = 5
open("/etc/host.conf", O_RDONLY)        = 5
open("/etc/hosts", O_RDONLY)            = 5
open("/etc/ld.so.cache", O_RDONLY)      = 5
open("/lib/libnss_dns.so.2", O_RDONLY)  = 5
open("/etc/hosts", O_RDONLY)            = 5
open("/etc/hosts", O_RDONLY)            = 5
open("/etc/hosts", O_RDONLY)            = 5
#加载自定义的配置文件
open("/Data/apps/nginx/conf/fastcgi_params", O_RDONLY|O_LARGEFILE) = 5
open("/Data/apps/nginx/conf/fastcgi_params", O_RDONLY|O_LARGEFILE) = 5
open("/Data/apps/nginx/conf/fastcgi_params", O_RDONLY|O_LARGEFILE) = 5
open("/Data/apps/nginx/conf/dyw.cdn.conf", O_RDONLY|O_LARGEFILE) = 5
open("/Data/apps/nginx/conf/fastcgi_params", O_RDONLY|O_LARGEFILE) = 6
the configuration file /Data/apps/nginx/conf/nginx.conf syntax is ok
open("/Data/apps/nginx/logs/nginx.pid", O_RDWR|O_CREAT|O_LARGEFILE, 0644) = 4
open("/Data/logs/error.nginx.log", O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE, 0644) = 4
configuration file /Data/apps/nginx/conf/nginx.conf test is successful
Process 18083 detached



2 监测程序做了什么,用php为例

写个测试的代码

<?
echo "test";
file_get_contents('http://www.baidu.com');
sleep(3);
file_put_contents('/tmp/test.php.txt','test');



先看看执行概况:

strace -c /Data/apps/php/bin/php test.php
test% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
59.91    0.000263           0      7977           select
32.35    0.000142           0      7985           poll
  4.10    0.000018           1        29           munmap
  2.51    0.000011           0       159           mmap
...



看上面的代码,select和poll其实是网络操作

strace -tt /Data/apps/php/bin/php test.php

12:30:59.371957 execve("/Data/apps/php/bin/php", ["/Data/apps/php/bin/php", "test.php"], [/* 26 vars */]) = 0
...
#尝试加载的路径优先级
12:30:59.372570 open("/Data/apps/mysql/lib/mysql/tls/x86_64/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
12:30:59.372599 stat("/Data/apps/mysql/lib/mysql/tls/x86_64", 0x7ffff6f97f40) = -1 ENOENT (No such file or directory)
12:30:59.372626 open("/Data/apps/mysql/lib/mysql/tls/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
12:30:59.372653 stat("/Data/apps/mysql/lib/mysql/tls", 0x7ffff6f97f40) = -1 ENOENT (No such file or directory)
12:30:59.372679 open("/Data/apps/mysql/lib/mysql/x86_64/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
12:30:59.372708 stat("/Data/apps/mysql/lib/mysql/x86_64", 0x7ffff6f97f40) = -1 ENOENT (No such file or directory)
12:30:59.372737 open("/Data/apps/mysql/lib/mysql/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
12:30:59.372765 stat("/Data/apps/mysql/lib/mysql", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
12:30:59.372824 open("/etc/ld.so.cache", O_RDONLY) = 3
...
12:30:59.389336 access("/Data/apps/php/bin/php", X_OK) = 0
#看看读取了哪个配置文件
12:30:59.389380 open("/Data/apps/php/bin/php-cli.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
12:30:59.389413 open("/Data/apps/php/etc/php-cli.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
12:30:59.389443 open("/Data/apps/php/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
12:30:59.389472 open("/Data/apps/php/etc/php.ini", O_RDONLY) = 3
...
#读取配置文件
12:30:59.389773 read(3, "[PHP]\n\n;;;;;;;;;;;\n; WARNING ;\n;"..., 8192) = 8192
12:30:59.389886 read(3, "ay only alter environment variab"..., 8192) = 8192
...
#加载配置文件的模块
12:30:59.391577 open("/Data/apps/php/lib/php/extensions/no-debug-non-zts-20060613/memcache.so", O_RDONLY) = 3
12:30:59.391612 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 <\0\0\0\0\0\0"..., 832) = 832
12:30:59.391641 fstat(3, {st_mode=S_IFREG|0755, st_size=237176, ...}) = 0
12:30:59.391677 mmap(NULL, 2154224, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f1ff8fa9000
12:30:59.391705 mprotect(0x7f1ff8fb6000, 2097152, PROT_NONE) = 0
12:30:59.391732 mmap(0x7f1ff91b6000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xd000) = 0x7f1ff91b6000
12:30:59.391814 close(3)                = 0
...
#eaccelerator尝试建立文件夹
12:30:59.400960 mkdir("/Data/cache/eaccelerator_cache/0", 0777) = -1 EEXIST (File exists)
12:30:59.401002 umask(0)                = 0
...
#读取执行的php文件
12:30:59.416912 open("test.php", O_RDONLY) = 3
...
#关闭该文件
12:30:59.417840 close(3)                = 0
12:30:59.417866 munmap(0x7f1ffff83000, 4096) = 0
12:30:59.417906 write(1, "test", 4test)     = 4
...
#socket通信
12:30:59.418067 socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 3
12:30:59.418099 close(3)                = 0
12:30:59.418136 socket(PF_NETLINK, SOCK_RAW, 0) = 3
12:30:59.418162 bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
12:30:59.418189 getsockname(3, {sa_family=AF_NETLINK, pid=2889, groups=00000000}, [12]) = 0
...
#输出了第一句 echo
12:30:59.418215 sendto(3, "\24\0\0\0\26\0\1\3\203r>R\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
...
#检查www.baidu.com的域名指向
12:30:59.418559 open("/etc/host.conf", O_RDONLY) = 3
...
12:30:59.418826 open("/etc/resolv.conf", O_RDONLY) = 3
...
12:30:59.419021 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3
...
#获得DNS服务器为 202.102.224.68,建立通信查询域名
12:30:59.419743 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("202.102.224.68")}, 16) = 0
...
#获得域名解析 指向 61.135.169.105
12:30:59.574172 connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("61.135.169.105")}, 16) = 0
...
#发出http请求啦
12:30:59.709654 sendto(3, "GET / HTTP/1.1\r\nUser-Agent: PHP/"..., 76, MSG_NOSIGNAL, NULL, 0) = 76
12:30:59.709713 poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
12:30:59.709759 select(4, [3], [3], [], {15, 0}) = 1 (out [3], left {14, 999998})
...大量 poll select
12:31:01.615348 recvfrom(3, "><script>var bdUser = null;var w"..., 3816, 0, NULL, NULL) = 3816
...
#休眠3秒
12:31:01.615462 close(3)                = 0
12:31:01.615620 nanosleep({3, 0}, 0x7ffff6f95f00) = 0
#写入文件
12:31:04.615796 lstat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=32768, ...}) = 0
12:31:04.615853 lstat("/tmp/test.php.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
12:31:04.615906 open("/tmp/test.php.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
12:31:04.615972 fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
12:31:04.616011 lseek(3, 0, SEEK_CUR)   = 0
12:31:04.616040 write(3, "test", 4)     = 4
12:31:04.616082 close(3)                = 0
12:31:04.616198 close(2)                = 0
12:31:04.616228 close(1)                = 0
12:31:04.616252 munmap(0x7f1ffff81000, 4096) = 0
12:31:04.616279 close(0)                = 0
12:31:04.616302 munmap(0x7f1ffff82000, 4096) = 0
12:31:04.616428 munmap(0x7f1ff8b39000, 2526280) = 0
12:31:04.616475 munmap(0x7f1ff8860000, 2985232) = 0
12:31:04.616508 munmap(0x7f1ff84eb000, 3624424) = 0
12:31:04.616556 munmap(0x3770a00000, 2162768) = 0
12:31:04.616587 munmap(0x7f1ff82de000, 2150272) = 0
12:31:04.616626 munmap(0x7f1ff8da2000, 2124096) = 0
12:31:04.616671 munmap(0x7f1ff8fa9000, 2154224) = 0
12:31:04.617215 munmap(0x7f1ff91b7000, 2205048) = 0
12:31:04.617618 exit_group(0)           = ?


你可能感兴趣的:(File,程序,监控,做什么)