strace 是一個(gè)非常簡(jiǎn)單的工具,用來(lái)跟蹤可執(zhí)行程序的系統(tǒng)調(diào)用(system call)。最簡(jiǎn)單的使用是,它追蹤可行程序運(yùn)行時(shí)的整個(gè)生命周期,輸出每一個(gè)系統(tǒng)調(diào)用的名字,參數(shù)和返回值。
我們注重客戶提出的每個(gè)要求,我們充分考慮每一個(gè)細(xì)節(jié),我們積極的做好做網(wǎng)站、網(wǎng)站制作服務(wù),我們努力開(kāi)拓更好的視野,通過(guò)不懈的努力,成都創(chuàng)新互聯(lián)贏得了業(yè)內(nèi)的良好聲譽(yù),這一切,也不斷的激勵(lì)著我們更好的服務(wù)客戶。 主要業(yè)務(wù):網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),微信平臺(tái)小程序開(kāi)發(fā),網(wǎng)站開(kāi)發(fā),技術(shù)開(kāi)發(fā)實(shí)力,DIV+CSS,PHP及ASP,ASP.Net,SQL數(shù)據(jù)庫(kù)的技術(shù)開(kāi)發(fā)工程師。
但是它還可以做更多的事情:
它可以基于系統(tǒng)調(diào)用或者系統(tǒng)調(diào)用組來(lái)過(guò)濾
它可以通過(guò)計(jì)算制定系統(tǒng)調(diào)用的次數(shù),花費(fèi)的時(shí)間以及成功和失敗的次數(shù)來(lái)描述系統(tǒng)調(diào)用的使用
它可以追蹤發(fā)送給進(jìn)程的信號(hào)(signal)
它可以通過(guò)進(jìn)程id(pid)號(hào)加入到任意正在運(yùn)行的進(jìn)程上
如何使用
這里只是簡(jiǎn)單的描述strace如何使用,并不打算對(duì)此做深入分析
找出一個(gè)程序啟動(dòng)時(shí)讀取了哪個(gè)配置文件
有的時(shí)候,你發(fā)發(fā)現(xiàn),無(wú)論你如何修改配置文件,應(yīng)用程序并沒(méi)有按照你的思路去運(yùn)行,這是什么原因?一個(gè)淺顯但容易忽視的考慮是,應(yīng)用程序啟動(dòng)時(shí)讀取了你認(rèn)為要讀取的配置文件了嗎?看下面的例子:
$ strace php 2>&1 | grep php.ini open("/usr/local/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/local/lib/php.ini", O_RDONLY) = 4 lstat64("/usr/local/lib/php.ini", {st_mode=S_IFLNK|0777, st_size=27, ...}) = 0 readlink("/usr/local/lib/php.ini", "/usr/local/Zend/etc/php.ini", 4096) = 27 lstat64("/usr/local/Zend/etc/php.ini", {st_mode=S_IFREG|0664,st_size=40971, ...}) = 0
上述php程序程序會(huì)首先從/usr/local/bin/下讀取php.ini文件,也許不是你想的首先從/usr/local/lib/下讀取。
上述的輸出會(huì)很多,我們甚至可以通過(guò)參數(shù)來(lái)指定只追蹤我們關(guān)心的系統(tǒng)調(diào)用,類(lèi)似如下:
$ strace -e open php 2>&1 | grep php.ini open("/usr/local/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/local/lib/php.ini", O_RDONLY) = 4
為什么程序沒(méi)有打開(kāi)我的文件?
每一個(gè)可執(zhí)行程序讀取文件時(shí),如果權(quán)限不夠,則會(huì)遭拒絕。而如果文件找不到,也并不會(huì)報(bào)錯(cuò),除非你在程序里設(shè)置了錯(cuò)誤處理,So,如果程序沒(méi)有讀取我的文件,我該如何跟蹤呢?
$ strace -e open,access 2>&1 |grep your-filename
檢查open()和access()系統(tǒng)調(diào)用的輸出結(jié)果,看看是什么原因
進(jìn)程此刻正在做什么?
你的程序突然消耗了大量的CPU,或者程序似乎被掛起了,那么我們通過(guò)進(jìn)程的pid號(hào)看看此刻它正在做什么
root@dev:~# strace -p 15427 Process 15427 attached - interrupt to quit futex(0x402f4900, FUTEX_WAIT, 2, NULL Process 15427 detached
通過(guò)跟蹤,你知道程序掛起的原因是正在調(diào)用futex()。
程序的時(shí)間花在什么地方
你總是希望程序能夠按照你的意愿去工作,也希望它能在正確的時(shí)間做正確的事情,甚至希望它是最優(yōu)的,盡可能在程序運(yùn)行的周期內(nèi),消耗的90%以上的資源都是在做需要做的事情,而不是簡(jiǎn)單的等待。也許,下面的這個(gè)指令可以幫上你的忙:
root@dev:~# strace -c -p 11084
Process 11084 attached - interrupt to quit
Process 11084 detached
% time seconds usecs/call calls errors syscall
94.59 0.001014 48 21 select
2.89 0.000031 1 21 getppid
2.52 0.000027 1 21 time
100.00 0.001072 63 total
root@dev:~#
如果你是跟蹤的后臺(tái)守護(hù)進(jìn)程,可以通過(guò)上面的指令跟蹤一段時(shí)間,然后按ctrl+c退出,strace會(huì)根據(jù)獲得信息描述出上面的結(jié)果。
上述的例子說(shuō)明當(dāng)前進(jìn)程(postmaster)最要的時(shí)間花在等待select()函數(shù)上,在每調(diào)用一次select函數(shù)后,它分別調(diào)用getpid函數(shù)和time函數(shù). 如果是非后臺(tái)守護(hù)進(jìn)程,那strace可以跟蹤進(jìn)程的開(kāi)始至結(jié)束,類(lèi)似下面這樣:
root@dev:~# strace -c >/dev/null ls
% time seconds usecs/call calls errors syscall
23.62 0.000205 103 2 getdents64
18.78 0.000163 15 11 1 open
15.09 0.000131 19 7 read
12.79 0.000111 7 16 old_mmap
7.03 0.000061 6 11 close
4.84 0.000042 11 4 munmap
4.84 0.000042 11 4 mmap2
4.03 0.000035 6 6 6 access
3.80 0.000033 3 11 fstat64
1.38 0.000012 3 4 brk
0.92 0.000008 3 3 3 ioctl
0.69 0.000006 6 1 uname
0.58 0.000005 5 1 set_thread_area
0.35 0.000003 3 1 write
0.35 0.000003 3 1 rt_sigaction
0.35 0.000003 3 1 fcntl64
0.23 0.000002 2 1 getrlimit
0.23 0.000002 2 1 set_tid_address
0.12 0.000001 1 1 rt_sigprocmask
100.00 0.000868 87 10 total
ls程序大部分時(shí)間花在讀取目錄條目上面。
為什么我不能連接到服務(wù)器?
調(diào)試進(jìn)程不能連接到服務(wù)器是一個(gè)痛苦的事情,因?yàn)樵蚝芏啵热鏒NS失效啦,連接被掛起啦,服務(wù)器返回異常數(shù)據(jù)啦,服務(wù)器本身異常啦,等等。一般網(wǎng)絡(luò)調(diào)試方面,很多人會(huì)想到另外一個(gè)非常不錯(cuò)的工具-tcpdump。但它的參數(shù)太多了,而且你要從上百個(gè)連接進(jìn)程中找出其中一個(gè)進(jìn)程為什么不能連接恐怕是一件非常費(fèi)力的工作。strace 其實(shí)也能在這種情景下幫上你的忙,它僅僅輸出與系統(tǒng)調(diào)用相關(guān)的數(shù)據(jù),從而可以讓我們的注意力更集中。類(lèi)似下面這樣:
$ strace -e poll,select,connect,recvfrom,sendto nc http://www.news.com 80
sendto(3, "\24\0\0\0\26\0\1\3\255\373NH\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0
poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
sendto(3, "\213\321\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\34\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30
poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
recvfrom(3, "\213\321\201\200\0\1\0\1\0\1\0\0\3www\4news\3com\0\0\34\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 153
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0
poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
sendto(3, "k\374\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\1\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30
poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
recvfrom(3, "k\374\201\200\0\1\0\2\0\0\0\0\3www\4news\3com\0\0\1\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 106
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0
poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
sendto(3, "\\2\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\1\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30
poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
recvfrom(3, "\\2\201\200\0\1\0\2\0\0\0\0\3www\4news\3com\0\0\1\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 106
connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("216.239.122.102")}, 16) = -1 EINPROGRESS (Operation now in progress)
select(4, NULL, [3], NULL, NULL) = 1 (out [3])
那么,上述的輸出,說(shuō)明進(jìn)程發(fā)生了什么呢?
注意到這個(gè)進(jìn)程嘗試連接/var/run/nscd/socket連接了嗎?這意味著nc程序首先會(huì)去連接NSCD- Name Service Cache Daemon - 它通常用于設(shè)置和NIS,YP,LDAP或者類(lèi)似目錄協(xié)議相關(guān)的域名查詢配置上。在上述例子中,連接失敗了。
接下來(lái)進(jìn)程開(kāi)始連接到DNS,這點(diǎn)可以從sin_port=htons(53)輸出可以看出。你可以看到,它接著做了一個(gè)sendto()的調(diào)用,發(fā)出了一個(gè)包含http://www.news.com信息的DNS包。然后讀取返回的包數(shù)據(jù),不知什么原因,它做了三次這樣的嘗試。一個(gè)可能的原因是http://www.news.com是一條CNAME記錄。多次請(qǐng)求可能是nc程序處理的一種方式。
最后,它總算是發(fā)起了connect()操作,注意這個(gè)操作的返回結(jié)果是EINPROGRESS,這意味著這個(gè)連接是非阻塞式的,nc希望繼續(xù),于是它調(diào)用了select()。
增加read,write調(diào)用到strace跟蹤的系統(tǒng)調(diào)用列表里,可以讓我們看到下面的一些結(jié)果:
read(0, "test\n", 1024) = 5
write(3, "test\n", 5) = 5
poll([{fd=3, events=POLLIN, revents=POLLIN}, {fd=0, events=POLLIN}], 2, -1) = 1
read(3, "
上述表示它從讀取”test” + 標(biāo)準(zhǔn)輸入的一行信息,然后寫(xiě)入網(wǎng)絡(luò)連接,接著調(diào)用poll來(lái)等待回應(yīng),然后讀取網(wǎng)絡(luò)反饋的信息并寫(xiě)到標(biāo)準(zhǔn)輸出。
當(dāng)前名稱:使用strace工具故障排查的5種簡(jiǎn)單方法
URL網(wǎng)址:http://vcdvsql.cn/article48/podghp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、服務(wù)器托管、軟件開(kāi)發(fā)、網(wǎng)站排名、建站公司、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)