Linux中國

strace 可以解決什麼問題?

昨天我 在 Twitter 上詢問大家用 strace 解決了什麼問題?,和往常一樣,大家真的是給出了自己的答案! 我收到了大約 200 個答案,然後花了很多時間手動將它們歸為 9 類。

這些解決的問題都是關於尋找程序依賴的文件、找出程序卡住或慢的原因、或者找出程序失敗的原因。這些總體上與我自己使用 strace 的內容相吻合,但也有一些我沒有想到的東西!

我不打算在這篇文章里解釋什麼是 strace,但我有一本 關於它的免費雜誌一個講座 以及 很多博文

問題 1:配置文件在哪裡?

最受歡迎的問題是「這個程序有一個配置文件,但我不知道它在哪裡」。這可能也是我最常使用 strace 解決的問題,因為這是個很簡單的問題。

這很好,因為一個程序有一百萬種方法來記錄它的配置文件在哪裡(在手冊頁、網站上、--help等),但只有一種方法可以讓它真正打開它(用系統調用!)。

問題 2:這個程序還依賴什麼文件?

你也可以使用 strace 來查找程序依賴的其他類型的文件,比如:

問題 3:為什麼這個程序會掛掉?

你有一個程序,它只是坐在那裡什麼都不做,這是怎麼回事?這個問題特別容易回答,因為很多時候你只需要運行 strace -p PID,看看當前運行的是什麼系統調用。你甚至不需要看幾百行的輸出。

答案通常是「正在等待某種 I/O」。「為什麼會卡住」的一些可能的答案(雖然還有很多!):

  • 它一直在輪詢 select()
  • 正在 wait() 等待一個子進程完成
  • 它在向某個沒有響應的東西發出網路請求
  • 正在進行 write(),但由於緩衝區已滿而被阻止。
  • 它在 stdin 上做 read(),等待輸入。

有人還舉了一個很好的例子,用 strace 調試一個卡住的 df 命令:「用 strace df -h 你可以找到卡住的掛載,然後卸載它」。

問題 4:這個程序卡住了嗎?

這是上一個問題的變種:有時一個程序運行的時間比你預期的要長,你只是想知道它是否卡住了,或者它是否還在繼續進行。

只要程序在運行過程中進行系統調用,用 strace 就可以超簡單地回答這個問題:只需 strace 它,看看它是否在進行新的系統調用!

問題 5:為什麼這個程序很慢?

你可以使用 strace 作為一種粗略的剖析工具:strace -t 會顯示每次系統調用的時間戳,這樣你就可以尋找大的漏洞,找到罪魁禍首。

以下是 Twitter 上 9 個人使用 strace 調試「為什麼這個程序很慢?」的小故事。

  • 早在 2000 年,我幫助支持的一個基於 Java 的網站在適度的負載下奄奄一息:頁面載入緩慢,甚至完全載入不出來。我們對 J2EE 應用伺服器進行了測試,發現它每次只讀取一個類文件。開發人員沒有使用 BufferedReader,這是典型的 Java 錯誤。
  • 優化應用程序的啟動時間……運行 strace 可以讓人大開眼界,因為有大量不必要的文件系統交互在進行(例如,在同一個配置文件上反覆打開/讀取/關閉;在一個緩慢的 NFS 掛載上載入大量的字體文件,等等)。
  • 問自己為什麼在 PHP 中從會話文件中讀取(通常是小於 100 位元組)非常慢。結果發現一些 flock 系統調用花了大約 60 秒。
  • 一個程序表現得異常緩慢。使用 strace 找出它在每次請求時,通過從 /dev/random 讀取數據並耗盡熵來重新初始化其內部偽隨機數發生器。
  • 我記得最近一件事是連接到一個任務處理程序,看到它有多少網路調用(這是意想不到的)。
  • strace 顯示它打開/讀取同一個配置文件數千次。
  • 伺服器隨機使用 100% 的 CPU 時間,實際流量很低。原來是碰到打開文件數限制,接受一個套接字時,得到 EMFILE 錯誤而沒有報告,然後一直重試。
  • 一個工作流運行超慢,但是沒有日誌,結果它做一個 POST 請求花了 30 秒而超時,然後重試了 5 次……結果後台服務不堪重負,但是也沒有可視性。
  • 使用 strace 注意到 gethostbyname() 需要很長時間才能返回(你不能直接看到 gethostbyname,但你可以看到 strace 中的 DNS 數據包)

問題 6:隱藏的許可權錯誤

有時候程序因為一個神秘的原因而失敗,但問題只是有一些它沒有許可權打開的文件。在理想的世界裡,程序會報告這些錯誤(「Error opening file /dev/whatever: permission denied」),當然這個世界並不完美,所以 strace 真的可以幫助解決這個問題!

這其實是我最近使用 strace 做的事情。我使用了一台 AxiDraw 繪圖儀,當我試圖啟動它時,它列印出了一個難以理解的錯誤信息。我 strace 它,結果發現我的用戶沒有許可權打開 USB 設備。

問題 7:正在使用什麼命令行參數?

有時候,一個腳本正在運行另一個程序,你想知道它傳遞的是什麼命令行標誌!

幾個來自 Twitter 的例子。

  • 找出實際上是用來編譯代碼的編譯器標誌
  • 由於命令行太長,命令失敗了

問題 8:為什麼這個網路連接失敗?

基本上,這裡的目標是找到網路連接的域名 / IP 地址。你可以通過 DNS 請求來查找域名,或者通過 connect 系統調用來查找 IP。

一般來說,當 tcpdump 因為某些原因不能使用或者只是因為比較熟悉 strace 時,就經常會使用 strace 調試網路問題。

問題 9:為什麼這個程序以一種方式運行時成功,以另一種方式運行時失敗?

例如:

  • 同樣的二進位程序在一台機器上可以運行,在另一台機器上卻失敗了
  • 可以運行,但被 systemd 單元文件生成時失敗
  • 可以運行,但以 su - user /some/script 的方式運行時失敗
  • 可以運行,作為 cron 作業運行時失敗

能夠比較兩種情況下的 strace 輸出是非常有用的。雖然我在調試「以我的用戶身份工作,而在同一台計算機上以不同方式運行時卻失敗了」時,第一步是「看看我的環境變數」。

我在做什麼:慢慢地建立一些挑戰

我之所以會想到這個問題,是因為我一直在慢慢地進行一些挑戰,以幫助人們練習使用 strace 和其他命令行工具。我的想法是,給你一個問題,一個終端,你可以自由地以任何方式解決它。

所以我的目標是用它來建立一些你可以用 strace 解決的練習題,這些練習題反映了人們在現實生活中實際使用它解決的問題。

就是這樣!

可能還有更多的問題可以用 strace 解決,我在這裡還沒有講到,我很樂意聽到我錯過了什麼!

我真的很喜歡看到很多相同的用法一次又一次地出現:至少有 20 個不同的人回答說他們使用 strace 來查找配置文件。而且和以往一樣,我覺得這樣一個簡單的工具(「跟蹤系統調用!」)可以用來解決這麼多不同類型的問題,真的很令人高興。

via: https://jvns.ca/blog/2021/04/03/what-problems-do-people-solve-with-strace/

作者:Julia Evans 選題:lujun9972 譯者:wxy 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國