Linux:strace 簡介

文章目錄

  • 1. 前言
  • 2. 什么是 strace ?
  • 3. 使用 strace
    • 3.1 追蹤指定進程
      • 3.1.1 通過程序名追蹤進程
      • 3.1.2 通過 進程 ID (PID) 追蹤程序
      • 3.1.3 追蹤 子進程 或 線程
    • 3.2 系統調用情況統計
    • 3.3 追蹤過濾
      • 3.3.1 追蹤指定的系統調用集合
      • 3.3.2 追蹤對指定文件句柄集合操作的系統調用
      • 3.3.3 追蹤訪問指定路徑的系統調用
      • 3.3.4 追蹤返回成功的系統調用
      • 3.3.5 追蹤返回錯誤碼的系統調用
      • 3.3.6 指定系統調用類別
    • 3.4 輸出控制
      • 3.4.1 輸出時間戳
      • 3.4.2 將追蹤結果寫入文件
    • 3.5 其它選項
  • 4. 交叉編譯 strace
  • 5. 參考資料

1. 前言

限于作者能力水平,本文可能存在謬誤,因此而給讀者帶來的損失,作者不做任何承諾。

2. 什么是 strace ?

straceLinux 下一款診斷、調試、追蹤工具,它可以用來監控和獲取內核的系統調用、信號投遞、進程狀態變更等信息。其基本實現機制是通過 ptrace() 系統調用,來獲取內核相關信息。對 strace 實現原理感興趣的讀者,可直接閱讀 strace 源碼,或參考博文 Linux:系統調用追蹤原理簡析 。

3. 使用 strace

3.1 追蹤指定進程

3.1.1 通過程序名追蹤進程

在程序啟動時,可通過 strace 跟蹤程序運行期間的所有系統調用。如:

# strace ls
execve("/bin/ls", ["ls"], 0xbeb73e50 /* 12 vars */) = 0
brk(NULL)                               = 0xc3000
uname({sysname="Linux", nodename="(none)", ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f0e000
...
stat64(".", {st_mode=S_IFDIR|0755, st_size=232, ...}) = 0
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3
getdents64(3, 0xc30b0 /* 3 entries */, 32768) = 80
lstat64("./tcp_server", {st_mode=S_IFREG|0755, st_size=11192, ...}) = 0
getdents64(3, 0xc30b0 /* 0 entries */, 32768) = 0
close(3) 
...
exit_group(0)                           = ?
+++ exited with 0 +++

上面的輸出,每一行顯示一個系統調用,包含系統調用名、調用參數、以及返回值(= 后的內容),譬如輸出:

openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3

表示調用了 open() ,打開的是當前目錄 "." ,傳遞的 flags 參數為 O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY,返回值為 3

3.1.2 通過 進程 ID (PID) 追蹤程序

首先找到目標進程的 PID:

# ps -ef | grep -v grep | grep InfiniteDsp160 root     ./InfiniteDsp

然后進行追蹤:

# strace -p 160
strace: Process 160 attached
read(27, "\1\0\0\0", 4)                 = 4
[......]

3.1.3 追蹤 子進程 或 線程

對于調用 fork()clone() 等系列接口的程序,在 3.1.1,3.1.2 基礎上,需再加上 -f--follow-forks 命令行參數來進程追蹤:

strace -f <program>
strace -fp <PID>

如有一個 PID 為 2622 的多線程程序,我們用 strace 來追蹤它:

# strace -fp 2622
strace: Process 2622 attached with 4 threads
[pid  2627] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2626] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2625] restart_syscall(<... resuming interrupted restart_syscall ...> <unfinished ...>
[pid  2622] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2626] <... restart_syscall resumed> ) = 0

從輸出看到,PID 為 2622 的進程有 4 個線程,同時輸出每行開頭都帶上了線程的 PID ,這樣就能知道每個系統調用是由哪個線程發起的。

3.2 系統調用情況統計

通過 -c-C 命令行參數,統計系統調用消耗的總時間、調用總次數、每次消耗的平均時間、出錯總次數等信息,并在結束追蹤時輸出這些信息。-c-C 的差別在于:-c 不會在追蹤期間輸出系統調用情況,而 -C 則相反。看一個簡單的例子:

# strace -C -fp 2622
strace: Process 2622 attached with 4 threads
[pid  2626] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2627] restart_syscall(<... resuming interrupted restart_syscall ...> <unfinished ...>
[pid  2625] restart_syscall(<... resuming interrupted restart_syscall ...> <unfinished ...>
[pid  2622] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2626] <... restart_syscall resumed> ) = 0
[......]
^Cstrace: Process 2622 detached<detached ...>
strace: Process 2625 detached
strace: Process 2626 detached
strace: Process 2627 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------84.95    0.000948         474         2           restart_syscall8.42    0.000094          47         2         2 inotify_add_watch6.63    0.000074          25         3         2 recvmsg
------ ----------- ----------- --------- --------- ----------------
100.00    0.001116                     7         4 total

3.3 追蹤過濾

3.3.1 追蹤指定的系統調用集合

有時候并不想追蹤程序所有的系統調用,通過下列選項

-e trace=syscall_set
-e t=syscall_set
--trace=syscall_set

指定想追蹤不想追蹤的系統調用集合。如只想追蹤程序的 open() 調用:

# strace -e t=open /bin/ls
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/proc/filesystems", O_RDONLY)     = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
[......]
+++ exited with 0 +++

strace 只輸出程序運行過程中所有 open() 調用。如果想追蹤多個系統調用,可以用 , 分隔,如:

# strace -e t=open,read /bin/ls
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260Z\0\0\0\0\0\0"..., 832) = 832
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\t\2\0\0\0\0\0"..., 832) = 832
open("/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\25\0\0\0\0\0\0"..., 832) = 832
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\r\0\0\0\0\0\0"..., 832) = 832
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260`\0\0\0\0\0\0"..., 832) = 832
open("/proc/filesystems", O_RDONLY)     = 3
read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tr"..., 1024) = 429
read(3, "", 1024)                       = 0
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
[......]
+++ exited with 0 +++

3.3.2 追蹤對指定文件句柄集合操作的系統調用

通過下列選項:

-e trace-fd=set
-e trace-fds=set
-e fd=set
-e fds=set

追蹤對指定文件句柄集合操作的系統調用。如追蹤所有對文件句柄 3 的操作:

# strace -e fd=3 /bin/ls
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\235h\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0777, st_size=898752, ...}) = 0
mmap2(NULL, 968040, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6e01000
mmap2(0xb6ee8000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xd7000) = 0xb6ee8000
close(3)                                = 0
getdents64(3, 0xc30b0 /* 14 entries */, 32768) = 456
getdents64(3, 0xc30b0 /* 0 entries */, 32768) = 0
close(3)                                = 0
[......]
+++ exited with 0 +++

3.3.3 追蹤訪問指定路徑的系統調用

通過下列選項:

-P path
--trace-path=path

追蹤指定訪問目錄的系統調用。

# strace --trace-path=/var /bin/ls /var
stat64("/var", {st_mode=S_IFDIR|0777, st_size=672, ...}) = 0
openat(AT_FDCWD, "/var", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3
getdents64(3, 0xc30b0 /* 10 entries */, 32768) = 256
getdents64(3, 0xc30b0 /* 0 entries */, 32768) = 0
close(3)                                = 0
[......]
+++ exited with 0 +++

3.3.4 追蹤返回成功的系統調用

通過下列選項:

-z
--successful-only

只追蹤返回成功的系統調用。

3.3.5 追蹤返回錯誤碼的系統調用

通過下列選項:

-Z
--failed-only

只追蹤返回錯誤碼的系統調用。

3.3.6 指定系統調用類別

從前面知道,下列選項

-e trace=syscall_set
-e t=syscall_set
--trace=syscall_set

可以指定要追蹤的系統調用集合。前面已經示范了通過具體的名字來指定集合,這里介紹通過類別指定系統調用集合的方式,即 syscall_set 還可以通過如下方式指定:

/regex : 正則表達式
%file, file: 追蹤文件操作相關的系統調用(open,close,access,...)
%process, process: 追蹤進程操作相關的系統調用(exec,...)
%net, %network, network: 追蹤網絡操作相關的系統調用(exec,...)
......

3.4 輸出控制

3.4.1 輸出時間戳

選項

-r 
--relative-timestamps[=precision]

輸出相對時間(相對于程序啟動時間):

# strace -r /bin/ls0.000000 execve("/bin/ls", ["/bin/ls"], [/* 26 vars */]) = 00.000589 brk(NULL)                 = 0x188c0000.000323 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)0.000285 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)0.000209 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 30.000335 fstat(3, {st_mode=S_IFREG|0644, st_size=100481, ...}) = 00.000566 mmap(NULL, 100481, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9a94f300000.000304 close(3)                  = 0[......]0.000096 exit_group(0)             = ?0.000101 +++ exited with 0 +++

選項

-t
--absolute-timestamps

輸出絕對時間:

# strace -t /bin/ls
11:18:35 execve("/bin/ls", ["/bin/ls"], [/* 26 vars */]) = 0
11:18:35 brk(NULL)                      = 0x14f0000
11:18:35 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
11:18:35 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
[......]

選項

-T
--syscall-times[=precision]

輸出每個系統調用消耗的時間:

# strace -T /bin/ls
execve("/bin/ls", ["/bin/ls"], [/* 26 vars */]) = 0 <0.000381>
brk(NULL)                               = 0x1701000 <0.000126>
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory) <0.000135>
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory) <0.000094>
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 <0.000084>
[......]

3.4.2 將追蹤結果寫入文件

選項

-o filename
--output=filename

將追蹤結果寫入文件。

3.5 其它選項

strace 的更多使用方法可參考其手冊 https://www.man7.org/linux/man-pages/man1/strace.1.html 。

4. 交叉編譯 strace

先獲取 strace 源碼(當前版本為 6.6):

git clone https://gitlab.com/strace/strace.git

交叉編譯 strace 源碼(假定目標平臺為 ARM32,交叉編譯器為 arm-linux-gnueabihf-gcc):

./bootstrap
CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld RANLIB=arm-linux-gnueabihf-ranlib \
./configure --prefix=$(pwd)/out --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
make && make install

將在 out 目錄下生成 strace 程序:

$ tree out
out
├── bin
│   ├── strace
│   └── strace-log-merge
└── share└── man└── man1├── strace.1└── strace-log-merge.1

5. 參考資料

[1] https://strace.io/
[2] https://www.man7.org/linux/man-pages/man1/strace.1.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166329.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166329.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166329.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端已死?看看我的秋招上岸歷程

背景 求職方向&#xff1a;web前端 技術棧&#xff1a;vue2、springboot&#xff08;學校開過課&#xff0c;簡單的學習過&#xff09; 實習經歷&#xff1a;兩段&#xff0c;但都是實訓類的&#xff0c;說白了就是類似培訓&#xff0c;每次面試官問起時我也會坦誠交代&…

關于鴻蒙網絡請求的問題

https://developer.huawei.com/consumer/cn/forum/topic/0204136145853212268?fid0102683795438680754 鴻蒙OS 代碼 import http from ohos.net.http;export const httpUtils (url: string, data: any) > {return new Promise((resolve, reject) > {let httpRequest …

創意設計與個性化定制:酒精壁爐的獨特之處

在當今家居裝飾的潮流中&#xff0c;人們越來越注重個性化和創意&#xff0c;而酒精壁爐正是在這一趨勢中嶄露頭角。它不僅成為家居的溫馨之選&#xff0c;更因其設計的靈活性而成為創意焦點&#xff0c;吸引了越來越多注重家居設計的人群。 酒精壁爐的設計靈活性為家居注入了新…

vue的package.json詳細說明

前言 package.json 文件是一個非常重要的文件,它用于存儲關于項目的元信息以及依賴項。在 Vue.js 項目中,package.json 文件描述了項目的名稱、版本、描述、作者、依賴項、腳本命令等信息。 說明 package.json 文件常見的 詳細說明: 1.名稱 (name): 項目的名稱。遵循反向…

工作流引擎架構設計

一個應用MIS的系統的架構離不開工作流引擎&#xff0c;具有流程引擎思維的架構人員設計系統的時候就有流程的思維&#xff0c;他區別于過程思維&#xff0c;過程思維開發出來的系統&#xff0c;用戶面對的是菜單、模塊。而流程思維設計出來的系統就是發起、待辦、在途、查詢、近…

SELinux refpolicy詳解(2)

接前一篇文章:SELinux refpolicy詳解(1) 本文內容引自: Documentation SELinuxProject/refpolicy Wiki GitHub 4. 入門指南 文檔是參考策略的主要目標之一。入門指南(https://github.com/SELinuxProject/refpolicy/wiki/GettingStarted)提供了有關編寫參考策略模塊的…

關于vue3項目中 vite.config.js項目配置 多個請求地址代理配置

關于VUE3 vite.config.js文件配置相關 提示&#xff1a;本文記錄了我們項目中使用到了多個不同的接口請求前綴地址配置代理&#xff0c;如果有更好的優化方案歡迎大佬指點呀&#xff1a; 以下是我最近項目中的vite.config.js文件配置&#xff0c;由于剛開始vue3不久&#xff…

JS 類型轉換機制

這篇寫得不錯&#xff1a; 百度安全驗證 包括顯示轉換&#xff08;就是調用函數&#xff09;、隱式轉換&#xff08;運算符 - 時自動轉換成數字/字符串&#xff09; 注意到&#xff1a; abc-1 //NaN 非法字符轉換為數字 結果是NaN

LeetCode 1410. HTML 實體解析器:字符串匹配

【LetMeFly】1410.HTML 實體解析器&#xff1a;字符串匹配 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/html-entity-parser/ 「HTML 實體解析器」 是一種特殊的解析器&#xff0c;它將 HTML 代碼作為輸入&#xff0c;并用字符本身替換掉所有這些特殊的字符實體。…

【點云surface】基于多項式重建的平滑和法線估計

1 介紹 基于多項式重建的平滑和法線估計&#xff08;Smoothing and normal estimation based on polynomial reconstruction&#xff09;是一種常用的點云處理方法&#xff0c;用于平滑點云數據并估計每個點的法線信息。 該方法基于Moving Least Squares&#xff08;MLS&…

docker安裝nacos,實現和mysql容器的通信

1.下載nacos鏡像 docker pull nacos/nacos-server2. 啟動nacos 啟動命令如下&#xff1a; docker run -d -p 8848:8848 --name nacos \ -e JVM_XMS256m \ -e JVM_XMX256m \ -e MODEstandalone \ -e SPRING_DATASOURCE_PLATFORMmysql \ -e MYSQL_SERVICE_HOST192.168.131.223…

連接的原理(待修改)

搞數據庫?個避不開的概念就是Join&#xff0c;翻譯成中?就是連接。 相信很多?伙伴在初學連接的時候有些?臉懵逼&#xff0c;理解了連接的語義之后?可能不明?各個表中的記 錄到底是怎么連起來的&#xff0c;以?于在使?的時候常常陷?下邊兩種誤區&#xff1a; 誤區?&…

linux磁盤清理

目錄 排查過程1、查看磁盤占用情況2. 按照占用大小進行倒排-當前目錄及其子目錄3.當前目錄磁盤占用情況 清理命令 排查過程 1、查看磁盤占用情況 df -hdf -h 命令用于顯示磁盤空間的使用情況&#xff0c;以人類可讀的方式呈現&#xff0c;其中&#xff1a;df 是 “disk free”…

“AI就緒”新計劃,亞馬遜云科技到2025年向200萬人提供免費AI技能培訓

AI就緒&#xff08;AI Ready&#xff09;計劃 到2025年為全球200萬人提供 免費人工智能&#xff08;AI&#xff09;技能培訓和教育資源 亞馬遜云科技宣布啟動“AI就緒&#xff08;AI Ready&#xff09;”計劃&#xff0c;旨在到2025年為全球200萬人提供免費人工智能&#xff08…

Python與設計模式--適配器模式

7-Python與設計模式–適配器模式 一、外包人員系統兼容 假設某公司A與某公司B需要合作&#xff0c;公司A需要訪問公司B的人員信息&#xff0c;但公司A與公司B協議接口不同&#xff0c; 該如何處理&#xff1f;先將公司A和公司B針對各自的人員信息訪問系統封裝了對象接口。cla…

易點易動固定資產管理系統:全生命周期管理的理想選擇

在現代企業中&#xff0c;固定資產管理是一項至關重要的任務。為了確保企業的資產安全、提高資產利用率&#xff0c;全面管理固定資產的生命周期至關重要。易點易動固定資產管理系統為企業提供了一種全面的解決方案&#xff0c;實現了從固定資產申購、采購、入庫、領用、退庫、…

linux 內存回收mglru算法代碼注釋2

mglru與原lru算法的兼容 舊的lru算法有active與inactive兩代lru&#xff0c;可參考linux 內存回收代碼注釋&#xff08;未實現多代lru版本&#xff09;-CSDN博客 新的算法在引入4代lru的同時&#xff0c;還引入了tier的概念。 新舊算法的切換的實現在lru_gen_change_state&a…

ELK企業級日志分析平臺——elasticsearch

集群部署 文檔&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/7.6/index.html 下載&#xff1a;https://elasticsearch.cn/download/ 主機 ip 角色 k8s1 192.168.92.11 cerebro elk1 192.168.92.31 elasticsearch elk2 192.168.92.32 elasti…

數據庫實驗五 數據庫設計

數據庫實驗五 數據庫設計 一、實驗目的二、實驗內容三、實驗內容四、驗證性實驗五、設計性實驗 一、實驗目的 1.了解E-R圖構成要素以及各要素圖元。 2.掌握概念模型E-R圖的繪制方法。 3.掌握概念模型向邏輯模型的轉換原則和步驟。 4.運用sql編程實現 二、實驗內容 1.選取一個…

線段樹---數據結構學習

線段樹的教程可以參照線段樹 這里推薦 https://oi-wiki.org/ 這個網站&#xff0c;數據結構講的非常透。 線段樹學了很多次忘了很多次&#xff0c;這次打算記錄一下以后方便回顧(leetcode這類題遇見的不算特別多)。 樣板例題 leltcode-307 #題目樣板 class NumArray {private …