如何在Linux上使用strace追蹤進程的系統呼叫?

2020-08-13 10:37:19

有時候,我們需要檢查執行中的應用程式在底層做了什麼,以及在執行過程中執行了什麼系統呼叫是很有用的。要在Linux上完成這樣的任務,我們可以使用strace實用程式。在本文中,我們將瞭解如何安裝它,並瞭解它的基本用法。
在本文中,您將瞭解到:
①如何安裝strace
②如何使用 strace 追蹤進程的系統呼叫?
③如何過濾具體的系統呼叫
④如何附加到一個已經執行的進程
⑤如何生成系統呼叫摘要
一、安裝strace
雖然預設情況下沒有安裝,但是strace實用程式可以在所有主要Linux發行版的官方儲存庫中使用,我們可以通過使用最喜歡的包管理器非常容易的安裝它。
如果我們執行在Fedora(或紅帽家族的任何其他發行版)上,我們必須使用dnf:
$ sudo dnf install strace
如果我們更習慣使用Debian或基於Debian的發行版(例如Ubuntu或Linux Mint),則可以使用apt來獲得相同的結果:
$ sudo apt install strace
如果使用的是Arch Linu,我們可以使用pacman來安裝應用程式,這是在提供額外的儲存庫:
$ sudo pacman -S strace
安裝軟體後,我們可以繼續進行操作,並檢視其用法範例。
二、strace介紹
就像我們已經說過的那樣,strace是一種工具,用於跟蹤正在執行的進程進行的系統呼叫以及該進程接收到的信號。系統呼叫是應用程式和Linux內核之間的基本介面。當我們使用strace時,進程進行的呼叫的名稱以及它們的參數和返回值將顯示在stderr(標準錯誤檔案描述符)上。
讓我們看一下strace的基本用法,以便熟悉其輸出。在其最基本的用法中,我們先將strace呼叫,然後再呼叫我們要執行的程式以及要分析其行爲的程式。對於此範例,我們將僅使用cp命令複製檔案:
$ strace cp ~/.bashrc bashrc
該命令的輸出很長,當然這裏我們不能詳細分析它。我們只看第一行。strace輸出的每一行都包含:
系統呼叫名稱
括號中傳遞給系統呼叫的參數
系統呼叫返回值
我們可以在輸出中看到的第一個系統呼叫是execve。該呼叫用於執行帶有指定參數陣列的程式。被接受的第一個參數execv是我們要執行的檔案的路徑;第二個是字串陣列,代表要傳遞給程式的參數(按照慣例,第一個參數是程式本身的名稱)。
在我們的例子中,被呼叫的二進制檔案是/usr/bin/cp,傳遞給該呼叫的參數陣列是:程式名稱(cp),源路徑和目標路徑:
execve("/usr/bin/cp", [「cp」, 「/home/egdoc/.bashrc」, 「bashrc」], 0x7fff53d4e4c0 /* 46 vars /) = 0
其中/
46 vars */符號表示從呼叫過程繼承了46個變數(在execv函數中,環境是從外部environ變數獲取的)。最後,我們有返回值是0(實際上exec,函數族僅在發生錯誤時才返回值)。
1、僅過濾特定的系統呼叫
在使用strace時,有時我們可能只想跟蹤進程進行的特定系統呼叫。在這種情況下,我們可以使用-e選項後跟一個表達式,該表達式指示應跟蹤的系統呼叫。假設我們執行與上一個範例相同的命令,但是我們只希望read系統呼叫顯示在輸出中,我們將執行:
$ strace -e read cp ~/.bashrc bashrc
順便說一句,該read系統呼叫有三個參數:第一個是一個 檔案描述符與應讀的檔案相關聯; 第二個是應讀取檔案的緩衝區,第三個 是應讀取的位元組數。成功後,該函數將返回從檔案讀取的位元組數,正如我們在上面的輸出中可以看到的那樣。
2、在正在執行的進程上附加strace
到現在爲止,我們呼叫strace傳遞給它要執行的命令並保持跟蹤;如果我們要跟蹤現有的並且已經在執行的流程該怎麼辦?在這種情況下,我們必須使用(或)選項呼叫strace,並傳遞要附加到其上的進程的PID(進程ID)。-p–attach
要找到程式的PID,在其他解決方案中,我們可以使用pidof 實用程式。爲了這個範例,我們將strace附加到正在執行的gnome-terminal-server範例:
$ pidof gnome-terminal-server
121316
返回的pidof命令121316是gnome-terminal-server的PID。知道了這一點,我們可以將strace附加到流程中:
$ strace -p 121316
「 strace -p 121316」命令的輸出
上面的輸出將在執行系統呼叫時「即時」更新。要「分離」 曲線,我們只需按Ctrl+C一下鍵盤即可。我們將收到有關「分離」的通知,但是跟蹤的過程將繼續執行:
strace: Process 121316 detached
3、追蹤信號
通過strace,我們還可以觀察到進程何時接收到信號,以及它如何對信號做出反應。演示一下,首先,我們作爲top啓動一個長期執行的進程,它是一個進程監視器:
$ top
然後,在獲得其PID後,我們將strace附加到它,在這種情況下爲 44825:
$ strace -p 44825
此時,strace開始跟蹤top發出的系統呼叫,以及它接收到的信號。爲了證明這一點,我們將SIGTERM發送給PID 44825:
$ kill 44825
如預期的那樣,該事件在strace輸出中報告:
— SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=44888, si_uid=1000} —
在上面的輸出中,si_signo是要傳送的信號數(SIGTERM = 15), si_code包含標識信號原因的程式碼(SI_USER = 0):在這種情況下,信號是由使用者進程生成的。的si_pid和si_uid 欄位報告,分別PID發送進程的和其UID。
4、將strace的輸出儲存到檔案中
如果在啓動strace時使用-o選項(的縮寫–ouput),則可以將其輸出重定向到檔案,並通過路徑作爲參數,例如:
$ strace -p 121316 -o strace_output
strace: Process 121316 attached
該strace_output檔案將被建立和輸出strace的會裏面寫。要觀看檔案中的更新,我們可以使用tail:通常,此命令讀取檔案的最後10行並退出,但是如果我們使用-f選項(short --follow)進行呼叫,則可以觀察到附加了新內容:
$ tail -f strace_output
5、列印系統呼叫摘要
該strace的工具配備了一個非常有用的功能:產生一個指定的進程的所有系統呼叫的總結的能力。如果要生成這樣的報告,我們要做的就是使用-c或–summary-only選項呼叫程式 。讓我們以以前使用的cp命令爲例:
$ strace -c cp ~/.bashrc bashrc
上面的命令將生成此報告:
在这里插入图片描述
由於我們生成了摘要,因此 不會顯示strace的正常輸出。如果我們要生成摘要但仍獲得程式的常規輸出,則必須使用-C選項,即summary。
在本文中,我們學習瞭如何安裝和使用strace,這是一個很好的實用程式,可用於偵錯目的,並且更廣泛地用於跟蹤進程執行的系統呼叫。我們看到了strace的輸出是如何組織的,如何啓動程式並跟蹤它所進行的系統呼叫,如何將strace附加 到已經執行的進程以及如何通知進程接收到的信號。最後,我們看到瞭如何生成流程所有呼叫的摘要。
A5互聯https://www.a5idc.net/