Linux调试分析诊断利器----strace
? ? strace是個功能強大的Linux調試分析診斷工具,可用于跟蹤程序執行時進程系統調用(system call)和所接收的信號,尤其是針對源碼不可讀或源碼無法再編譯的程序。
? ? 在Linux系統中,用戶程序運行在一個沙箱(sandbox)里,用戶進程不能直接訪問計算機硬件設備。當進程需要訪問硬件設備(如讀取磁盤文件或接收網絡數據等)時,必須由用戶態模式切換至內核態模塊,通過系統調用訪問硬件設備。strace可跟蹤進程產生的系統調用,包括參數、返回值和執行所消耗的時間。若strace沒有任何輸出,并不代表此時進程發生阻塞;也可能程序進程正在自己的沙箱里執行某些不需要與系統其它部分發生通信的事情。strace從內核接收信息,且無需以任何特殊方式來構建內核。
? ? strace命令格式如下:
strace [-dffhiqrtttTvVxx] [-a column] [-e expr] [-o file] [-p pid] [-s strsize] [-u username] [-E var=val] ...]] 或
strace -c [-e expr] [-O overhead] [-S sortby] [-E var=val] [command [arg ...]]]
? ? 通過不同的選項開關,strace提供非常豐富的跟蹤功能。最簡單的應用是,跟蹤可執行程序運行時的整個生命周期,將所調用的系統調用的名稱、參數和返回值輸出到標準錯誤stderr(即屏幕)或-o選項所指定的文件。注意,命令(command)必須位于選項列表之后。
? ? 詳細的strace命令選項列舉如下:
? ??
| 選項 | 含義 |
| -c | 統計和報告每個系統調用所執行的時間、調用次數和出錯次數等 |
| -d | 輸出strace關于標準錯誤的調試信息 |
| -f | 跟蹤當前進程及其通過fork系統調用所創建的子進程 |
| -ff | 常與-o選項聯合使用,不同進程(子進程)的跟蹤結果分別輸出到相應的filename.pid文件中,pid是各個進程號 |
| -F | 嘗試跟蹤vfork系統調用。否則即使打開-f選項,vfork也不會被跟蹤 |
| -h | 顯示幫助信息 |
| -i | 顯示發生系統調用時的指令指針(IP)寄存器值 |
| -q | 抑制(禁止輸出)關于結合(attaching)、脫離(detaching)的消息。當輸出重定向到一個文件時,自動抑制此類消息 |
| -r | 顯示每個系統調用發生時的相對時間戳,即連續的系統調用起點之間的時間差 |
| -t -tt -ttt | -t在每行輸出前添加絕對時間戳(當前時鐘)信息,精確到妙級 -tt在每行輸出前添加絕對時間戳信息,精確到微妙級 -ttt在每行輸出前添加相對時間信息,格式為"自紀元時間起經歷的秒數.微秒數" |
| -T | 顯示每個系統調用所耗費的時間,其時間開銷在輸出行最右側的尖括號內 |
| -V | 顯示strace的版本信息 |
| -v | 冗余顯示模式:顯示系統調用中argv[]、envp[]、stat、termio(s)等數組/結構體參數所有的元素/成員內容。這些數組/結構體因使用頻繁,默認僅顯示其元素/成員的合理子集 |
| -x | 以16進制形式顯示非標準(non-ascii)字符串,如"/x08"。默認為8進制,如"/10" |
| -xx | 以16進制形式顯示所有字符串 |
| -a column | 設置顯示系統掉一個呢返回值的列位置,默認為40(從0開始),即"="出現在第40列 |
| -e expr | 指定一個表達式,用于限定跟蹤哪些事件及如何跟蹤。其格式為[qualifier=][!]all或[qualifier=][!]value1[,value2]...。 qualifier取值為trace(默認)、abbrev、verbose、raw、signal、read或write。value是用于限定的符號(包括all和none)或數字。感嘆號為否定符號,如-eopen等價于-e trace=open,表示只跟蹤open系統調用;而-e trace=!open表示跟蹤除open外的其他系統調用。 注意某些shell用!表示執行理事記錄里的命令,此時可能借助引號、轉義符號(/)。 -e trace=set: 跟蹤指定的系統調用列表,如-e trace=open,close,read,write表示只跟蹤這四種系統調用。默認為set=all。 -e trace=file: 跟蹤以指定文件名做參數的所有系統調用。 -e trace=process: 跟蹤涉及進程管理的所有系統調用,可用于觀察進程的fork、wait或exec階段。 -e trace=network:跟蹤網絡相關的所有系統調用。 -e strace=signal: 跟蹤所有與系統間通信有關的系統調用。 -e trace=ipc: 跟蹤所有與進程間通信有關的系統調用。 -e abbrev=set: 指定哪些系統調用中的大型數組或結構體內容縮減顯示,如strace -e abbrev=execve ./test僅顯示execve調用中argv[]和envp[]的部分內容。默認為abbrev=all,abbrev=none等價于-v選項。 -e verbose=set:指定哪些系統調用中的大型數組或結構體內容完整顯示,集合外的調用其數組或結構體顯示為地址。默認為verbose=all。 -e raw=set: 指定哪些系統調用中的參數以原始未解碼的形式(即16進制)顯示。當用戶不信任strace解碼或需要了解參數實際數值時有用。 -e signal=set: 跟蹤指定的信號列表,默認為signal=all。如signal=!SIGIO(或signal=!io)表示不跟蹤SIGIO信號。 -e read=set:跟蹤指定的信號列表,默認為signal=all。如signal=!SIGIO(或signal=!io)表示不跟蹤SIGIO信號。 -e read=set:以16進制和ASCII碼對照形式顯示從指定文件描述符中讀出的所有數據,如-e read=3,5可觀察文件描述符3和5上的輸入動作。該選項獨立與系統調用read的常規跟蹤(由-e trace=read選項控制)。 -e write=set : 以16進制和ASCII碼對照形式顯示寫入指定文件描述符的所有數據。 |
| -o file | strace輸出信息默認顯示到標準錯誤輸出,該選項將輸出信息寫入文件file中。以下兩條命令等效: strace -c -o test.txt ./test strace -c ./test 2>test.txt |
| -O overhead | Set the overhead for tracing system calls to overhead microseconds. This is useful for overriding the default heuristic for guessing how much time is spent in mere measuring when timing system calls using the -c option. The acuracy of the heuristic can be gauged by timing a given program run without tracing (使用time命令) and comparing the accumulated system call time to the total produced using -c. |
| -p pid | 指定待跟蹤的進程號(pid),可用Ctrl-C終止跟蹤而被跟蹤進程繼續運行??芍付ǘ噙_32個(-p pid)選項以同時跟蹤多個進程,該選項常用于調試后臺進程 |
| -s strsize | 限制每行輸出中字符串(如read參數)的最大顯示長度,默認32字節。但文件名總是完整顯示 |
| -S sortby | 按指定規則對-c選項的輸出直方圖進行排序。sortby取值可為time、calls、name和nothing(默認time) |
| -u username | 用指定用戶的UID和/或GID身份運行待跟蹤程序 |
| -E var=val | 將var=val放入命令的環境變量列表 |
| -E var | 從命令的環境變量列表中移除var |
? ? 例如,命令strace -o out.txt -T -tt -e trace=all -p 2899表示跟蹤2899進程的所有系統調用,并統計系統調用的事件開銷,以及調用起始事件(以可視化的時分秒格式顯示),最后將記錄結果存入out.txt文件。
? ? 為便于說明,使用strace跟蹤ls -l命令執行過程(strace ls -l),前幾行輸出如下:
strace記錄程序所產生的每次系統調用,并以類似C的格式(無論創建該程序時使用何種編程語言)各自顯示為單獨的一行。每行起始為系統調用的函數名,括號內為參數,該調用的返回值則顯示在等號右側。當參數為數組或結構體時,顯示其元素(方括號)或成員(花括號)內容,見execve和fstat64.當參數為bit時,使用方括號并用空格隔開每項參數,如sigprocmask(SIG_BLOCK,[CHLD TTOU],[]) = 0,第二個參數代表信號SIGCHLD和SIGTTOU;若bit型參數全部置位,則輸出如sigprocmask(SIG_UNBLOCK,~[],NULL) = 0,此處第二個參數全部置位。
? ? 通過使用-c選項,strace可統計分析進程所有的系統調用(strace -c ./ChangeSysTime),如:
? ??
? ? 可看到程序調用哪些系統函數,調用次數、所耗時間及出錯次數等信息,有助于分析程序運行速度瓶頸。同時注意到,settimeofday調用出錯兩次,而該函數在ChangeSysTime程序中被顯式調用兩次,亦即這兩次調用均出錯!但ChangeSysTime程序中并未對settimeofday調用作出錯處理,故在運行中沒有輸出任何錯誤提示。假定程序源碼不可修改,則此時就可借助strace找出錯誤所在(strace -e trace=settimeofday ./ChangeSysTime):?
?真相大白,原來調用settimeofday函數時因操作權限不夠而被拒絕(需要root權限)!注意,第2、3和5行輸出為ChangeSysTime程序打印輸出。
轉自:https://www.cnblogs.com/clover-toeic/p/3738156.html
總結
以上是生活随笔為你收集整理的Linux调试分析诊断利器----strace的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx_hash表
- 下一篇: nginx会话保持值sticky模块