[R] 如何用樹展示linux C函數調用棧 - collapsibleTree

效果如下:

視頻封面

01:05linux C語言函數棧

此例展示的是linux最常用的系統調用 - open()的函數調用樹

-----

推薦 linux C函數流程圖 以及linux文件樹

老白Walt:[R+bash] 5分鐘內製作一張linux C函數流程圖 - DiagrammeR

老白Walt:[R] 展示linux文件樹 - collapsibleTree


1 獲取數據

1.1 函數調用棧

cflow - 一款生成函數調用棧的命令行工具

舉個例子:

cflow

用法就是這樣子:

cflow -m 函數名 文件名

直接輸出調用棧,以縮進表示stack depth,贊!不過如果我將include/, block/, mm/目錄的文件都加進來的話,這個stack會非常非常長,在shell下看會崩潰,因此這裡要發揮R語言的優勢

不過在進入R之前還有一個問題: 這個數據格式R語言可沒有東東認得!經過一番搜尋發現一條可行的數據轉換的path:

[shell] cflow -> grep/perl/sed -> .yaml -> [R] -> yaml::yaml.load_file -> data.tree::as.Node

最終可以轉換為Node格式,就可以優雅地用collapsibleTree來展示了

而連接shell和R的東東就是YAML

註:cflow是有BUG的,並不是總能很好的解析函數,所以不能過度依賴

1.2 YAML

下面就是YAML的一種格式

a_nested_map:
key: value
another_key: Another Value
another_nested_map:
hello: hello

key: value而value也可以是多個key: value對

cflow的輸出正好有縮進,我只需要把key: value給轉換好即可

1.3 cflow -> YAML

find fs/*.* fs/notify include/linux/ -name *.[ch] | grep -Pv w*(?:pr_|print|trace|lock) | xargs cflow -m vfs_open 2> /dev/null | sed -r /^s*(pr_[^(]+|printk|ssize_t|loff_t)()/d | perl -pe s/^(s*)([^(]+)()(?:$|s+<.* at ([^>]+)>.*$)/12:
1 file: 3/ > open.yaml

find fs/*.* fs/sysfs fs/notify include/linux/ -name *.[ch] | grep -Pv w*(?:pr_|print|trace|lock)

用find找fs和include下的.c和.h,再用grep過濾掉一些debug的文件

open()函數定義在fs/open.c:

不過因其定義是宏展開的,cflow還沒有強大到可以捕獲,因此這裡跳到vfs_open()代替;另外靜態工具對函數指針無計可施,因此調用棧還無法深入到具體的文件系統

xargs cflow -m vfs_open 2> /dev/null

用cflow -m vfs_open生成調用棧

perl -pe s/^(s*)([^(]+)()(?:$|s+<.* at ([^>]+)>.*$)/12:
1 file: 3/ > open.yaml

最後用perl將文本轉換為YAML格式:

至此,shell處理部分結束

2 R數據處理

2.1 載入YAML

yaml::yaml.load_file(d:/linux-master/open.yaml)

yaml包的yaml.load_file會將文件轉為list

2.2 YAML -> data.tree::Node

data.tree::as.Node(ylst)

data.tree包的as.Node方法會將其轉為Node class,它的功能是十分豐富的,有興趣的可以移步到下面鏈接:

https://cran.r-project.org/web/packages/data.tree/vignettes/data.tree.html?

cran.r-project.org

3 繪圖

yaml::yaml.load_file(d:/linux-master/open.yaml) %>%
data.tree::as.Node() %>%
collapsibleTree::collapsibleTree(
fill = orangered,
root = vfs_open,
width = 1850,
height = 900,
attribute = file,
tooltip = T
)

可喜的是滑鼠移動到節點上,可以顯示函數定義所在的文件和行數

啃linux源碼終於不用在紙上畫了


本專欄只生產乾貨,喜歡請關註:

數據及可視化?

zhuanlan.zhihu.com圖標
推薦閱讀:

TAG:Linux內核 | R(編程語言) | C/C |