System-Calls

從 strace 日誌中過濾掉失敗的系統呼叫

  • June 3, 2020

我可以strace像這樣執行命令sleep 1 並查看它正在訪問的文件是這樣的:

strace -e trace=file -o strace.log sleep 1

但是,在我的機器上,許多呼叫的返回值為 -1,表示該文件不存在。例如:

$ grep '= -1 ENOENT' strace.log | head
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.UTF-8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.UTF-8/LC_MEASUREMENT", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.UTF-8/LC_TELEPHONE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.UTF-8/LC_ADDRESS", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.UTF-8/LC_NAME", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.UTF-8/LC_PAPER", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

我對不存在的文件並不真正感興趣,我想知道該程序實際找到並讀取了哪些文件。除了grep -v '=-1 ENOENT',我怎樣才能可靠地過濾掉失敗的呼叫?

附錄

我很驚訝地得知自 2002 年以來一直以標誌strace的形式在作品中使用此功能,這是自 5.2 版2019-07-12 )起功能齊全的別名,也可從 5.6 版2020- 04-07)。-z``-e status=successful``--successful-only

-z從 5.2 版開始也可以使用,-Z標誌的補充-e status=failed,它是--failed-only5.6 版的別名。

-z標誌最初是在 2002 年的送出中添加的,並在版本 4.5.18 ( 2008-08-28 ) 中發布,它從未被記錄,因為它無法正常工作。

相關連結:

  • 只看到成功的系統呼叫

2002 年 11 月 2 日星期六晚上 11:07:23 UTC

使用 strace 時,我有時喜歡查看有效的系統呼叫(而不是所有系統呼叫)。

多年來我一直在移植這個更新檔,它似乎非常有用。

使用 -z 選項,您不會看到打開不存在的文件(跟踪程序實際執行的操作非常有用,而不是嘗試執行)。

https://lists.strace.io/pipermail/strace-devel/2002-November/000232.html

  • strace:-z 選項無法正常工作

日期:2003 年 1 月 12 日星期日 09:33:01 UTC

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=176376

  • 僅跟踪失敗的系統呼叫

創建時間:2004-03-19

https://sourceforge.net/p/strace/feature-requests/3/

  • $$ strace-4.15 $$建議:-z 選項的輸出暫存(僅列印成功的系統呼叫)/包含更新檔 2017 年 1 月 17 日星期二 09:35:54 UTC

https://lists.strace.io/pipermail/strace-devel/2017-January/005941.html

  • $$ PATCH v1 $$為失敗/成功的系統呼叫實現輸出暫存 2017 年 1 月 18 日星期三 16:01:20 UTC

https://lists.strace.io/pipermail/strace-devel/2017-January/005950.html

  • 修復 -z 選項

2018 年 2 月 28 日

https://github.com/strace/strace/issues/49

  • $$ PATCH 0/3 $$-z 和新的 -Z 選項的階段輸出 2019 年 4 月 1 日星期一 21:13:02 UTC

https://lists.strace.io/pipermail/strace-devel/2019-April/008706.html

  • strace -z 標誌

世界標準時間 6 月 10 日星期一 05:29:19

https://lists.strace.io/pipermail/strace-devel/2019-June/008808.html

除了對strace輸出進行後處理外,沒有任何東西可以忽略strace. 添加不會太難,看看syscall_exiting_trace.syscall.c

如果您更願意追求後期處理的角度,Ole Tange已經為您提供了比您可能在這裡獲得的更全面的方式:該tracefile工具將執行strace並過濾掉您需要的資訊一種很好讀的時尚。有關詳細資訊,請參閱列出程序訪問的文件該問題的另一個答案列出了其他可能的方法,包括我認為非常有用的LoggedFS 。

另一種選擇是使用SystemTap;例如

#!/usr/bin/env stap

global stored_filename, stored_path

probe syscall.open {
 stored_filename = filename
}

probe syscall.open.return {
 if (execname() == "cat" && $return >= 0) {
   printf("opened %s\n", stored_filename)
 }
}

probe syscall.openat {
 stored_filename = filename
 stored_path = dfd_str
}

probe syscall.openat.return {
 if (execname() == "cat" && $return >= 0) {
   printf("opened %s in %s\n", stored_filename, stored_path)
 }
}

cat將顯示任何程序成功打開的任何文件的名稱。

引用自:https://unix.stackexchange.com/questions/436074