亚洲韩日午夜视频,欧美日韩在线精品一区二区三区,韩国超清无码一区二区三区,亚洲国产成人影院播放,久草新在线,在线看片AV色

您好,歡迎來到思海網(wǎng)絡(luò),我們將竭誠為您提供優(yōu)質(zhì)的服務(wù)! 誠征網(wǎng)絡(luò)推廣 | 網(wǎng)站備案 | 幫助中心 | 軟件下載 | 購買流程 | 付款方式 | 聯(lián)系我們 [ 會員登錄/注冊 ]
促銷推廣
客服中心
業(yè)務(wù)咨詢
有事點擊這里…  531199185
有事點擊這里…  61352289
點擊這里給我發(fā)消息  81721488
有事點擊這里…  376585780
有事點擊這里…  872642803
有事點擊這里…  459248018
有事點擊這里…  61352288
有事點擊這里…  380791050
技術(shù)支持
有事點擊這里…  714236853
有事點擊這里…  719304487
有事點擊這里…  1208894568
有事點擊這里…  61352289
在線客服
有事點擊這里…  531199185
有事點擊這里…  61352288
有事點擊這里…  983054746
有事點擊這里…  893984210
當前位置:首頁 >> 技術(shù)文章 >> 文章瀏覽
技術(shù)文章

Llinux系統(tǒng)strace命令用法

添加時間:2016-8-14 1:42:38  添加: 思海網(wǎng)絡(luò) 

Llinux系統(tǒng)strace命令用法

 

調(diào)用:

strace [ -dffhiqrtttTvxx ] [ -acolumn ] [ -eexpr ] ...

[ -ofile ] [ -ppid ] ... [ -sstrsize ] [ -uusername ] [ command [ arg ... ] ]

 

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

功能:

跟蹤程式執(zhí)行時的系統(tǒng)調(diào)用和所接收的信號.通常的用法是strace執(zhí)行一直到commande結(jié)束.

并且將所調(diào)用的系統(tǒng)調(diào)用的名稱、參數(shù)和返回值輸出到標準輸出或者輸出到-o指定的文件.

strace是一個功能強大的調(diào)試,分析診斷工具.你將發(fā)現(xiàn)他是一個極好的幫手在你要調(diào)試一個無法看到源碼或者源碼無法在編譯的程序.

你將輕松的學習到一個軟件是如何通過系統(tǒng)調(diào)用來實現(xiàn)他的功能的.而且作為一個程序設(shè)計師,你可以了解到在用戶態(tài)和內(nèi)核態(tài)是如何通過系統(tǒng)調(diào)用和信號來實現(xiàn)程序的功能的.

strace的每一行輸出包括系統(tǒng)調(diào)用名稱,然后是參數(shù)和返回值.這個例子:

strace cat /dev/null

他的輸出會有:

open(\\"/dev/null\\",O_RDONLY) = 3

有錯誤產(chǎn)生時,一般會返回-1.所以會有錯誤標志和描述:

open(\\"/foor/bar\\",)_RDONLY) = -1 ENOENT (no such file or directory)

信號將輸出喂信號標志和信號的描述.跟蹤并中斷這個命令\\"sleep 600\\":

sigsuspend({}

--- SIGINT (Interrupt) ---

+++ killed by SIGINT +++

參數(shù)的輸出有些不一致.如shell命令中的 \\">>tmp\\",將輸出:

open(\\"tmp\\",O_WRONLY|O_APPEND|A_CREAT,0666) = 3

對于結(jié)構(gòu)指針,將進行適當?shù)娘@示.如:\\"ls -l /dev/null\\":

lstat(\\"/dev/null\\",{st_mode=S_IFCHR|0666},st_rdev=makdev[1,3],...}) = 0

請注意\\"struct stat\\" 的聲明和這里的輸出.lstat的第一個參數(shù)是輸入?yún)?shù),而第二個參數(shù)是向外傳值.

當你嘗試\\"ls -l\\" 一個不存在的文件時,會有:

lstat(/foot/ball\\",0xb004) = -1 ENOENT (no such file or directory)

char*將作為C的字符串類型輸出.沒有字符串輸出時一般是char* 是一個轉(zhuǎn)義字符,只輸出字符串的長度.

當字符串過長是會使用\\"...\\"省略.如在\\"ls -l\\"會有一個gepwuid調(diào)用讀取password文件:

read(3,\\"root::0:0:System Administrator:/\\"...,1024) = 422

當參數(shù)是結(jié)構(gòu)數(shù)組時,將按照簡單的指針和數(shù)組輸出如:

getgroups(4,[0,2,4,5]) = 4

關(guān)于bit作為參數(shù)的情形,也是使用方括號,并且用空格將每一項參數(shù)隔開.如:

sigprocmask(SIG_BLOCK,[CHLD TTOU],[]) = 0

這里第二個參數(shù)代表兩個信號SIGCHLD 和 SIGTTOU.如果bit型參數(shù)全部置位,則有如下的輸出:

sigprocmask(SIG_UNBLOCK,~[],NULL) = 0

這里第二個參數(shù)全部置位.

 

參數(shù)說明:

-c 統(tǒng)計每一系統(tǒng)調(diào)用的所執(zhí)行的時間,次數(shù)和出錯的次數(shù)等.

-d 輸出strace關(guān)于標準錯誤的調(diào)試信息.

-f 跟蹤由fork調(diào)用所產(chǎn)生的子進程.

-ff 如果提供-o filename,則所有進程的跟蹤結(jié)果輸出到相應(yīng)的filename.pid中,pid是各進程的進程號.

-F 嘗試跟蹤vfork調(diào)用.在-f時,vfork不被跟蹤.

-h 輸出簡要的幫助信息.

-i 輸出系統(tǒng)調(diào)用的入口指針.

-q 禁止輸出關(guān)于脫離的消息.

-r 打印出相對時間關(guān)于,,每一個系統(tǒng)調(diào)用.

-t 在輸出中的每一行前加上時間信息.

-tt 在輸出中的每一行前加上時間信息,微秒級.

-ttt 微秒級輸出,以秒了表示時間.

-T 顯示每一調(diào)用所耗的時間.

-v 輸出所有的系統(tǒng)調(diào)用.一些調(diào)用關(guān)于環(huán)境變量,狀態(tài),輸入輸出等調(diào)用由于使用頻繁,默認不輸出.

-V 輸出strace的版本信息.

-x 以十六進制形式輸出非標準字符串

-xx 所有字符串以十六進制形式輸出.

-a column

設(shè)置返回值的輸出位置.默認為40.

-e expr

指定一個表達式,用來控制如何跟蹤.格式如下:

[qualifier=][!]value1[,value2]...

qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用來限定的符號或數(shù)字.默認的qualifier是 trace.感嘆號是否定符號.例如:

-eopen等價于 -e trace=open,表示只跟蹤open調(diào)用.而-etrace!=open表示跟蹤除了open以外的其他調(diào)用.有兩個特殊的符號 all 和 none.

注意有些shell使用!來執(zhí)行歷史記錄里的命令,所以要使用\\\\.

-e trace=set

只跟蹤指定的系統(tǒng)調(diào)用.例如:-e trace=open,close,rean,write表示只跟蹤這四個系統(tǒng)調(diào)用.默認的為set=all.

-e trace=file

只跟蹤有關(guān)文件操作的系統(tǒng)調(diào)用.

-e trace=process

只跟蹤有關(guān)進程控制的系統(tǒng)調(diào)用.

-e trace=network

跟蹤與網(wǎng)絡(luò)有關(guān)的所有系統(tǒng)調(diào)用.

-e strace=signal

跟蹤所有與系統(tǒng)信號有關(guān)的系統(tǒng)調(diào)用

-e trace=ipc

跟蹤所有與進程通訊有關(guān)的系統(tǒng)調(diào)用

-e abbrev=set

設(shè)定strace輸出的系統(tǒng)調(diào)用的結(jié)果集.-v 等與 abbrev=none.默認為abbrev=all.

-e raw=set

將指定的系統(tǒng)調(diào)用的參數(shù)以十六進制顯示.

-e signal=set

指定跟蹤的系統(tǒng)信號.默認為all.如signal=!SIGIO(或者signal=!io),表示不跟蹤SIGIO信號.

-e read=set

輸出從指定文件中讀出的數(shù)據(jù).例如:

-e read=3,5

-e write=set

輸出寫入到指定文件中的數(shù)據(jù).

-o filename

將strace的輸出寫入文件filename

-p pid

跟蹤指定的進程pid.

-s strsize

指定輸出的字符串的最大長度.默認為32.文件名一直全部輸出.

-u username

以username的UID和GID執(zhí)行被跟蹤的命令.

 

用strace調(diào)試程序

 

     在理想世界里,每當一個程序不能正常執(zhí)行一個功能時,它就會給出一個有用的錯誤提示,告訴你在足夠的改正錯誤的線索。但遺憾的是,我們不是生活在理想世界里,起碼不總是生活在理想世界里。有時候一個程序出現(xiàn)了問題,你無法找到原因。

 

這就是調(diào)試程序出現(xiàn)的原因。strace是一個必不可少的調(diào)試工具,strace用來監(jiān)視系統(tǒng)調(diào)用。你不僅可以調(diào)試一個新開始的程序,也可以調(diào)試一個已經(jīng)在運行的程序(把strace綁定到一個已有的PID上面)。

 

首先讓我們看一個真實的例子:

 

[BOLD]啟動KDE時出現(xiàn)問題[/BOLD]

 

前一段時間,我在啟動KDE的時候出了問題,KDE的錯誤信息無法給我任何有幫助的線索。

 

代碼:

 

_KDE_IceTransSocketCreateListener: failed to bind listener

_KDE_IceTransSocketUNIXCreateListener: ...SocketCreateListener() failed

_KDE_IceTransMakeAllCOTSServerListeners: failed to create listener for local

 

Cannot establish any listening sockets DCOPServer self-test failed.

 

 

對我來說這個錯誤信息沒有太多意義,只是一個對KDE來說至關(guān)重要的負責進程間通信的程序無法啟動。我還可以知道這個錯誤和ICE協(xié)議(Inter Client Exchange)有關(guān),除此之外,我不知道什么是KDE啟動出錯的原因。

 

我決定采用strace看一下在啟動dcopserver時到底程序做了什么:

 

代碼:

 

strace -f -F -o ~/dcop-strace.txt dcopserver

 

 

這里 -f -F選項告訴strace同時跟蹤fork和vfork出來的進程,-o選項把所有strace輸出寫到~/dcop-strace.txt里面,dcopserver是要啟動和調(diào)試的程序。

 

再次出現(xiàn)錯誤之后,我檢查了錯誤輸出文件dcop-strace.txt,文件里有很多系統(tǒng)調(diào)用的記錄。在程序運行出錯前的有關(guān)記錄如下:

 

代碼:

 

27207 mkdir("/tmp/.ICE-unix", 0777) = -1 EEXIST (File exists)

27207 lstat64("/tmp/.ICE-unix", {st_mode=S_IFDIR|S_ISVTX|0755, st_size=4096, ...}) = 0

27207 unlink("/tmp/.ICE-unix/dcop27207-1066844596") = -1 ENOENT (No such file or directory)

27207 bind(3, {sin_family=AF_UNIX, path="/tmp/.ICE-unix/dcop27207-1066844596"}, 3 = -1 EACCES (Permission denied)

27207 write(2, "_KDE_IceTrans", 13) = 13

27207 write(2, "SocketCreateListener: failed to "..., 46) = 46

27207 close(3) = 0 27207 write(2, "_KDE_IceTrans", 13) = 13

27207 write(2, "SocketUNIXCreateListener: ...Soc"..., 59) = 59

27207 umask(0) = 0 27207 write(2, "_KDE_IceTrans", 13) = 13

27207 write(2, "MakeAllCOTSServerListeners: fail"..., 64) = 64

27207 write(2, "Cannot establish any listening s"..., 39) = 39

 

 

其中第一行顯示程序試圖創(chuàng)建/tmp/.ICE-unix目錄,權(quán)限為0777,這個操作因為目錄已經(jīng)存在而失敗了。第二個系統(tǒng)調(diào)用(lstat64)檢查了目錄狀態(tài),并顯示這個目錄的權(quán)限是0755,這里出現(xiàn)了第一個程序運行錯誤的線索:程序試圖創(chuàng)建屬性為0777的目錄,但是已經(jīng)存在了一個屬性為 0755的目錄。第三個系統(tǒng)調(diào)用(unlink)試圖刪除一個文件,但是這個文件并不存在。這并不奇怪,因為這個操作只是試圖刪掉可能存在的老文件。

 

但是,第四行確認了錯誤所在。他試圖綁定到/tmp/.ICE-unix/dcop27207-1066844596,但是出現(xiàn)了拒絕訪問錯誤。. ICE_unix目錄的用戶和組都是root,并且只有所有者具有寫權(quán)限。一個非root用戶無法在這個目錄下面建立文件,如果把目錄屬性改成0777,則前面的操作有可能可以執(zhí)行,而這正是第一步錯誤出現(xiàn)時進行過的操作。

 

所以我運行了chmod 0777 /tmp/.ICE-unix之后KDE就可以正常啟動了,問題解決了,用strace進行跟蹤調(diào)試只需要花很短的幾分鐘時間跟蹤程序運行,然后檢查并分析輸出文件。

 

說 明:運行chmod 0777只是一個測試,一般不要把一個目錄設(shè)置成所有用戶可讀寫,同時不設(shè)置粘滯位(sticky bit)。給目錄設(shè)置粘滯位可以阻止一個用戶隨意刪除可寫目錄下面其他人的文件。一般你會發(fā)現(xiàn)/tmp目錄因為這個原因設(shè)置了粘滯位。KDE可以正常啟動之后,運行chmod +t /tmp/.ICE-unix給.ICE_unix設(shè)置粘滯位。

 

[BOLD]解決庫依賴問題[/BOLD]

 

starce 的另一個用處是解決和動態(tài)庫相關(guān)的問題。當對一個可執(zhí)行文件運行l(wèi)dd時,它會告訴你程序使用的動態(tài)庫和找到動態(tài)庫的位置。但是如果你正在使用一個比較老的glibc版本(2.2或更早),你可能會有一個有bug的ldd程序,它可能會報告在一個目錄下發(fā)現(xiàn)一個動態(tài)庫,但是真正運行程序時動態(tài)連接程序(/lib/ld-linux.so.2)卻可能到另外一個目錄去找動態(tài)連接庫。這通常因為/etc/ld.so.conf和 /etc/ld.so.cache文件不一致,或者/etc/ld.so.cache被破壞。在glibc 2.3.2版本上這個錯誤不會出現(xiàn),可能ld-linux的這個bug已經(jīng)被解決了。

 

盡管這樣,ldd并不能把所有程序依賴的動態(tài)庫列出來,系統(tǒng)調(diào)用dlopen可以在需要的時候自動調(diào)入需要的動態(tài)庫,而這些庫可能不會被ldd列出來。作為glibc的一部分的NSS (Name Server Switch)庫就是一個典型的例子,NSS的一個作用就是告訴應(yīng)用程序到哪里去尋找系統(tǒng)帳號數(shù)據(jù)庫。應(yīng)用程序不會直接連接到NSS庫,glibc則會通過dlopen自動調(diào)入NSS庫。如果這樣的庫偶然丟失,你不會被告知存在庫依賴問題,但這樣的程序就無法通過用戶名解析得到用戶ID了。讓我們看一個例子:

 

whoami程序會給出你自己的用戶名,這個程序在一些需要知道運行程序的真正用戶的腳本程序里面非常有用,whoami的一個示例輸出如下:

代碼:

 

# whoami

root

 

 

假設(shè)因為某種原因在升級glibc的過程中負責用戶名和用戶ID轉(zhuǎn)換的庫NSS丟失,我們可以通過把nss庫改名來模擬這個環(huán)境:

代碼:

 

# mv /lib/libnss_files.so.2 /lib/libnss_files.so.2.backup

# whoami

whoami: cannot find username for UID 0

 

 

這里你可以看到,運行whoami時出現(xiàn)了錯誤,ldd程序的輸出不會提供有用的幫助:

代碼:

 

# ldd /usr/bin/whoami

libc.so.6 => /lib/libc.so.6 (0x4001f000)

/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

 

 

你只會看到whoami依賴Libc.so.6和ld-linux.so.2,它沒有給出運行whoami所必須的其他庫。這里時用strace跟蹤whoami時的輸出:

代碼:

 

strace -o whoami-strace.txt whoami

 

open("/lib/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/lib/i686/mmx/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

stat64("/lib/i686/mmx", 0xbffff190) = -1 ENOENT (No such file or directory)

open("/lib/i686/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

stat64("/lib/i686", 0xbffff190) = -1 ENOENT (No such file or directory)

open("/lib/mmx/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

stat64("/lib/mmx", 0xbffff190) = -1 ENOENT (No such file or directory)

open("/lib/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

stat64("/lib", {st_mode=S_IFDIR|0755, st_size=2352, ...}) = 0

open("/usr/lib/i686/mmx/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

stat64("/usr/lib/i686/mmx", 0xbffff190) = -1 ENOENT (No such file or directory)

open("/usr/lib/i686/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

 

 

你可以發(fā)現(xiàn)在不同目錄下面查找libnss.so.2的嘗試,但是都失敗了。如果沒有strace這樣的工具,很難發(fā)現(xiàn)這個錯誤是由于缺少動態(tài)庫造成的。現(xiàn)在只需要找到libnss.so.2并把它放回到正確的位置就可以了。

 

[BOLD]限制strace只跟蹤特定的系統(tǒng)調(diào)用[/BOLD]

 

如果你已經(jīng)知道你要找什么,你可以讓strace只跟蹤一些類型的系統(tǒng)調(diào)用。例如,你需要看看在configure腳本里面執(zhí)行的程序,你需要監(jiān)視的系統(tǒng)調(diào)用就是execve。讓strace只記錄execve的調(diào)用用這個命令:

 

代碼:

 

strace -f -o configure-strace.txt -e execve ./configure

 

 

部分輸出結(jié)果為:

代碼:

 

2720 execve("/usr/bin/expr", ["expr", "a", ":", "(a)"], [/* 31 vars */]) = 0

2725 execve("/bin/basename", ["basename", "./configure"], [/* 31 vars */]) = 0

2726 execve("/bin/chmod", ["chmod", "+x", "conftest.sh"], [/* 31 vars */]) = 0

2729 execve("/bin/rm", ["rm", "-f", "conftest.sh"], [/* 31 vars */]) = 0

2731 execve("/usr/bin/expr", ["expr", "99", "+", "1"], [/* 31 vars */]) = 0

2736 execve("/bin/ln", ["ln", "-s", "conf2693.file", "conf2693"], [/* 31 vars */]) = 0


關(guān)鍵字:Llinux、系統(tǒng)、strace命令
分享到:

頂部 】 【 關(guān)閉
版權(quán)所有:佛山思海電腦網(wǎng)絡(luò)有限公司 ©1998-2024 All Rights Reserved.
聯(lián)系電話:(0757)22630313、22633833
中華人民共和國增值電信業(yè)務(wù)經(jīng)營許可證: 粵B1.B2-20030321 備案號:粵B2-20030321-1
網(wǎng)站公安備案編號:44060602000007 交互式欄目專項備案編號:200303DD003  
察察 工商 網(wǎng)安 舉報有獎  警警  手機打開網(wǎng)站