1 什么是 strace strace 常用來(lái)跟蹤進(jìn)程執(zhí)行時(shí)的系統(tǒng)調(diào)用和所接收的信號(hào)。在 Linux 世界,進(jìn)程不能直接訪問(wèn)硬件設(shè)備,當(dāng)進(jìn)程需要訪問(wèn)硬件設(shè)備(比如讀取磁盤文件,接收網(wǎng)絡(luò)數(shù)據(jù)等等)時(shí),必須由用戶態(tài)模式切換至內(nèi)核態(tài)模式,通過(guò)系統(tǒng)調(diào)用訪問(wèn)硬件設(shè)備。 strace 可以跟蹤到一個(gè)進(jìn)程產(chǎn)生的系統(tǒng)調(diào)用,包括參數(shù),返回值,執(zhí)行消耗的時(shí)間。 2 什么是系統(tǒng)調(diào)用 系統(tǒng)調(diào)用(英語(yǔ):system call),又稱為系統(tǒng)呼叫,指運(yùn)行在用戶空間的程序向操作系統(tǒng)內(nèi)核請(qǐng)求需要更高權(quán)限運(yùn)行的服務(wù)。系統(tǒng)調(diào)用提供用戶程序與操作系統(tǒng)之間的接口。操作系統(tǒng)的進(jìn)程空間分為用戶空間和內(nèi)核空間: 操作系統(tǒng)內(nèi)核直接運(yùn)行在硬件上,提供設(shè)備管理、內(nèi)存管理、任務(wù)調(diào)度等功能。 用戶空間通過(guò) API 請(qǐng)求內(nèi)核空間的服務(wù)來(lái)完成其功能——內(nèi)核提供給用戶空間的這些 API, 就是系統(tǒng)調(diào)用 Linux 內(nèi)核目前有 300 多個(gè)系統(tǒng)調(diào)用,詳細(xì)的列表可以通過(guò) syscalls 手冊(cè)頁(yè)查看。這些系統(tǒng)調(diào)用主要分為幾類: 文件和設(shè)備訪問(wèn)類 比如 open/close/read/write/chmod 等 進(jìn)程管理類 fork/clone/execve/exit/getpid 等 信號(hào)類 signal/sigaction/kill 等 內(nèi)存管理 brk/mmap/mlock 等 進(jìn)程間通信 IPC shmget/semget * 信號(hào)量,共享內(nèi)存,消息隊(duì)列等 網(wǎng)絡(luò)通信 socket/connect/sendto/sendmsg 等 其他 查看系統(tǒng)調(diào)用幫助手冊(cè) man 2 函數(shù)名,例如下圖所示: ![]() 3 strace 的應(yīng)用場(chǎng)景 基于特定的系統(tǒng)調(diào)用或系統(tǒng)調(diào)用組進(jìn)行過(guò)濾 通過(guò)統(tǒng)計(jì)特定系統(tǒng)調(diào)用的使用次數(shù),所花費(fèi)的時(shí)間,以及成功和錯(cuò)誤的數(shù)量來(lái)分析系統(tǒng)調(diào)用的使用。 它跟蹤發(fā)送到進(jìn)程的信號(hào)。 通過(guò) pid 附加到任何正在運(yùn)行的進(jìn)程。 調(diào)試性能問(wèn)題,查看系統(tǒng)調(diào)用的頻率,找出耗時(shí)的程序段 查看程序讀取的是哪些文件從而定位比如配置文件加載錯(cuò)誤問(wèn)題 當(dāng)程序出現(xiàn)“Out of memory”時(shí)被系統(tǒng)發(fā)出的 SIGKILL 信息所 kill 另外因?yàn)?strace 拿到的是系統(tǒng)調(diào)用相關(guān)信息,一般也即是 IO 操作信息,這個(gè)對(duì)于排查比如 cpu 占用 100%問(wèn)題是無(wú)能為力的。這個(gè)時(shí)候就可以使用 GDB 工具了。 4 命令參數(shù) 我們輸入以下命令,可以查看 strace 命令的參數(shù)。 strace -h -c 統(tǒng)計(jì)每一系統(tǒng)調(diào)用的所執(zhí)行的時(shí)間,次數(shù)和出錯(cuò)的次數(shù)等. -d 輸出 strace 關(guān)于標(biāo)準(zhǔn)錯(cuò)誤的調(diào)試信息. -f 跟蹤由 fork 調(diào)用所產(chǎn)生的子進(jìn)程. -ff 如果提供-o filename,則所有進(jìn)程的跟蹤結(jié)果輸出到相應(yīng)的 filename.pid 中,pid 是各進(jìn)程的進(jìn)程號(hào). -F 嘗試跟蹤 vfork 調(diào)用.在-f 時(shí),vfork 不被跟蹤. -h 輸出簡(jiǎn)要的幫助信息. -i 輸出系統(tǒng)調(diào)用的入口指針. -q 禁止輸出關(guān)于脫離的消息. -r 打印出相對(duì)時(shí)間關(guān)于,,每一個(gè)系統(tǒng)調(diào)用. -t 在輸出中的每一行前加上時(shí)間信息. -tt 在輸出中的每一行前加上時(shí)間信息,微秒級(jí). -ttt 微秒級(jí)輸出,以秒了表示時(shí)間. -T 顯示每一調(diào)用所耗的時(shí)間. -v 輸出所有的系統(tǒng)調(diào)用.一些調(diào)用關(guān)于環(huán)境變量,狀態(tài),輸入輸出等調(diào)用由于使用頻繁,默認(rèn)不輸出. -V 輸出 strace 的版本信息. -x 以十六進(jìn)制形式輸出非標(biāo)準(zhǔn)字符串 -xx 所有字符串以十六進(jìn)制形式輸出. -a column 設(shè)置返回值的輸出位置.默認(rèn) 為 40. 5 實(shí)用示例 1 跟蹤已經(jīng)在運(yùn)行的進(jìn)程,使用-p 選項(xiàng)能用在運(yùn)行的進(jìn)程上,輸入以下命令: strace -p 進(jìn)程號(hào) 2 通過(guò) strace 啟動(dòng)要跟蹤的進(jìn)程,./hello.sh 是要運(yùn)行的文件,大家可以根據(jù)自己的需求自定義,如下所示: strace ./hello.sh ![]() |