如何使用 strace 監控 Linux 系統調用

已發表: 2022-01-29
筆記本電腦上的程式化終端窗口。
fatmawati achmad zaenuri/Shutterstock.com

Linux 程序要求內核為它們做一些事情。 strace命令顯示這些系統調用。 您可以使用它們來了解程序如何工作以及為什麼有時它們不工作。

內核和系統調用

儘管計算機程序可能很聰明,但它們不能為自己做所有事情。 他們需要請求為他們執行某些功能。 這些請求發送到 Linux 內核。 通常,程序調用一個庫或其他軟件接口,然後該庫向內核發出適當的請求(稱為系統調用)。

能夠查看程序進行的系統調用以及響應是什麼可以幫助您了解您感興趣或您編寫的程序的內部工作原理。 這就是strace的作用。 它可以幫助解決問題並尋找瓶頸。

這與使用gdb之類的工具調試應用程序不同。 調試程序可讓您調查程序運行時的內部操作。 它使您可以逐步執行程序的邏輯並檢查內存和變量值。 相比之下, strace所做的是在程序運行時捕獲系統調用信息。 當被跟踪的程序終止時, strace將系統調用信息列出到終端窗口。

系統調用提供各種低級功能,例如對文件的讀寫操作、終止進程等。 syscalls 手冊頁上有數百個系統調用的列表。

相關:使用 GDB 調試:入門

安裝 strace

如果您的計算機上尚未安裝strace ,您可以非常輕鬆地安裝它。

在 Ubuntu 上,使用以下命令:

 sudo apt install strace 

在 Fedora 上,鍵入以下命令:

 須藤 dnf 安裝 strace 

在 Manjaro 上,命令是:

 sudo pacman -Sy strace 

使用 strace 的第一步

我們將使用一個小程序來演示strace 。 它沒有做太多:它打開一個文件並向其中寫入一行文本,並且它沒有任何錯誤檢查。 這只是一個快速破解,以便我們可以使用strace

 #include <stdio.h>

int main(int argc, char argv[]) { 

  // 文件句柄 
  文件 *fileGeek;

  // 打開一個名為“strace_demo.txt”的文件,或者創建它 
  fileGeek = fopen("strace_demo.txt", "w");

  // 將一些文本寫入文件 
  fprintf(fileGeek, "將其寫入文件" );

  //關閉文件 
  fclose(文件極客);

  // 退出程序 
  返回(0); 

} // main 結束

我們將它保存到一個名為“file- io.c ”的文件中,並使用gcc將其編譯為一個名為stex的可執行文件,以“ st race example”命名。

 gcc -o stex 文件-io.c

我們將從命令行調用strace並將新可執行文件的名稱作為我們想要跟踪的進程傳遞給它。 我們可以輕鬆地跟踪任何 Linux 命令或任何其他二進制可執行文件。 我們使用我們的小程序有兩個原因。

第一個原因是strace很冗長。 可以有很多輸出。 當你在憤怒中使用strace時這很好,但一開始它可能會讓人不知所措。 我們的小程序的strace輸出有限。 第二個原因是我們的程序功能有限,源代碼簡短明了。 這使得更容易識別輸出的哪些部分引用了程序內部工作的不同部分。

 strace ./stex 

我們可以清楚地看到write系統調用將文本“Write this to the file”發送到我們打開的文件和exit_group系統調用。 這將終止應用程序中的所有線程並將返回值發送回 shell。

過濾輸出

即使使用我們簡單的演示程序,也有相當多的輸出。 我們可以使用-e (表達式)選項。 我們將傳入我們想要查看的系統調用的名稱。

 strace -e 寫./stex 

廣告

您可以通過將它們添加為逗號分隔的列表來報告多個系統調用。 不要在系統調用列表中包含任何空格。

 strace -e 關閉,寫入 ./stex 

將輸出發送到文件

過濾輸出的好處也是過濾輸出的問題。 你看到了你要求看到的東西,但你看不到其他任何東西。 並且其他一些輸出可能對您來說比您要求查看的內容更有用。

有時,捕獲所有內容並蒐索和滾動整個結果集會更方便。 這樣,您就不會意外排除任何重要的內容。 -o (輸出)選項允許您將strace會話的輸出發送到文本文件。

 strace -o 跟踪輸出.txt ./stex 

然後,您可以使用less命令滾動列表並按名稱搜索系統調用或其他任何內容。

 更少的trace-output.txt 

您現在可以使用所有less的搜索功能來調查輸出。

相關:如何在 Linux 上使用 less 命令

添加時間戳

您可以在輸出中添加幾個不同的時間戳。 -r (相對時間戳)選項添加時間戳,顯示每個連續系統調用開始之間的時間差。 請注意,這些時間值將包括上一次系統調用所花費的時間以及程序在下一次系統調用之前所做的任何其他事情。

 strace -r ./stex 

廣告

時間戳顯示在每行輸出的開頭。

要查看每個系統調用所花費的時間,請使用-T (系統調用時間)選項。 這顯示了在每個系統調用中花費的持續時間。

 strace -T ./stex 

持續時間顯示在每個系統調用行的末尾。

要查看調用每個系統調用的時間,請使用-tt (絕對時間戳)選項。 這顯示了“掛鐘”時間,分辨率為微秒。

 strace -tt ./stex 

時間顯示在每行的開頭。

跟踪正在運行的進程

如果您要跟踪的進程已經在運行,您仍然可以將strace附加到它。 為此,您需要知道進程 ID。 您可以使用psgrep來找到它。 我們正在運行 Firefox。 要找出firefox進程的 ID,我們可以使用ps並通過grep管道它。

 ps -e | grep 火狐

廣告

我們可以看到進程 ID 是 8483。我們將使用-p (進程 ID)選項告訴strace附加到哪個進程。 請注意,您需要使用sudo

 須藤 strace -p 8483 

您將看到一條通知,表明strace已將自身附加到進程,然後系統跟踪調用將照常顯示在終端窗口中。

創建報告

-c (僅限摘要)選項使strace打印報告。 它會生成一個表,以獲取有關被跟踪程序進行的系統調用的信息。

 strace -c ./stex 

這些列是:

  • % time :每個系統調用所花費的執行時間的百分比。
  • seconds :每個系統調用所花費的總時間,以秒和微秒錶示。
  • usecs/call :每個系統調用花費的平均時間(以微秒為單位)。
  • call :每個系統調用被執行的次數。
  • errors :每個系統調用的失敗次數。
  • syscall :系統調用的名稱。

對於快速執行和終止的瑣碎程序,這些值將顯示為零。 實際值顯示為比我們的演示應用程序更有意義的程序。

深入洞察,輕鬆

strace輸出可以顯示正在執行哪些系統調用,正在重複執行哪些系統調用,以及在內核端代碼中花費了多少執行時間。 這是很好的信息。 通常,當您試圖了解代碼內部發生的事情時,很容易忘記您的二進製文件幾乎不間斷地與內核交互以執行其許多功能。

通過使用strace ,您可以看到完整的畫面。

相關:適合開發人員和愛好者的最佳 Linux 筆記本電腦