從 strace 日誌中過濾掉失敗的系統呼叫
我可以
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-only
5.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
將顯示任何程序成功打開的任何文件的名稱。