登入  |  English
感謝您對「自由軟體鑄造場」的支持與愛護,十多年來「自由軟體鑄造場」受中央研究院支持,並在資訊科學研究所以及資訊科技創新研究中心執行,現已完成階段性的任務。 原網站預計持續維運至 2021年底,網站內容基本上不會再更動。本網站由 Denny Huang 備份封存。
也紀念我們永遠的朋友 李士傑先生(Shih-Chieh Ilya Li)。
新聞

CallGraphviz—依據 cscope、Graphviz 以及 xdot 實作的 call graph visualizer

開源工具現狀

許多開發者都有介入中大型專案的經驗,有時候也常常需要理解原始程式的設計,因此或多或少都有在程式碼迷宮中找路的經驗。有些專案,程式碼結構嚴謹,軟體設計時應用設計模式 (Design Patterns),往往只要見名稱、參數,即可推斷程式結構,閱讀上如沐春風。

但若碰到未經重構的成年老專案,程式邏輯因為年久失修,塞滿各個開發階段的臨時解決方案,常常已經複雜到難以一眼望穿理解。若是記憶力虛弱如我,常常追了後面幾千行、跳了三個檔,就忘了前面幾個檔案的函式名稱。於是常常以紙本畫流程圖輔助理解,但是手繪圖往往不敵跳來繞去的程式碼邏輯。還是得靠程式碼解析視覺化工具來協助理解。

繪製 call graph 的工具非常多,一般可以分作 dynamic analysisstatic analysis 兩種作法。在臺灣,最知名的商業版本工具,大概是 Source Insight。不過我不用 Windows,對於缺乏原始碼的開發工具興趣也不大。

開源的 dynamic analysis 包含諸如 Jserv 介紹過CodeViz 或是 ncc。不過這類工具需要 patch GCC,不適合嵌入式系統專案。因爲原始碼常常只支援特定平臺,或是無法取得編譯工具原始碼。此外,不同版本的 compiler 偶爾會造成不同的問題,造成使用上的困難。

一種比較乾淨的作法是像 KCachegrind 利用 valgrind 來收集資料,或 Gprof2Dot 利用 gprof 的輸出資料。再者是利用 GCC 的除錯功能,把 internal representation (RTL) 倒出來,再用 egyptPython-RTL 來判讀或繪圖。

至於開源的 static analysis,則包括 Fred Chien 介紹過cflow,或是 Doxygen 也有類似的繪圖功能。也有工具是配合 cscopeGLOBAL,例如有人幫 cscope 刻過圖形界面,Vim 有個 CCTree 可用。

CallGraphviz

以上這些工具各有優缺點。最常見的問題是許多工具無法處理 function pointerdynamic dispatch,最終還是需要人力介入。另外一個使用上的困擾是,這些程式會一口氣畫出整個程式碼的結構圖。

太多資訊其實妨礙理解,因爲用途常常只是追一個臭蟲,程式開發者只想畫出特定路徑來釐清問題。而 context-sensitive 的 call graph 測試工具又耗費資源。

若用 CodeLiteCode::BlocksEclipse CDT 等開發工具,這些工具已經內建或者整合了 cscopeGLOBAL,提供 symbol lookup 功能。開發者很容易用滑鼠查閱函式定義或實做,也可以搭配 LXR 來瀏覽程式碼。已經不需要像是 cbrowser 這類專屬的程式碼瀏覽工具。

如果需要手動將目前程式情境視覺化的工具,也可以在網路上找到。網路上已經有其他開發者做了 Bash: C Call Trees and Graphs 或是 global-calltree。或是像 Yao-Po Wang方法,記錄函式進出點,再手動繪圖。

上述工具大多是整合 shell scripts,操作上有點不便。另外我也不喜歡 Call Tree 的圖式,因爲樹狀圖無法表現遞迴或交互關係。

於是查找一下,決定拿 cscope 加上 GraphvizDOT 語法來用,改了一個 CallGraphviz。它的功能是以 Graphviz 做為前端,後端還是使用 cscope 查 symbols,為了可以即時瀏覽便取用 xdot 當作介面。xdot 是以 PyGtk 開發,非常容易更改,不到三百行就加入我需要的功能。

screenshotcodevisualize

▲ 圖1 使用 CallGraphviz 自動畫出的程式邏輯流程圖

使用方法:

* 執行 python visualizer.py
* 按下【New】,選擇要分析 C/C++ 專案目錄。
* 於「Search symbol」鍵入要追蹤的函式名稱。
* 每次鍵入新名稱,他會自動對應圖中已輸入函式是否爲 caller or callee,並自動畫圖。

CallGraphviz 可以將繪圖結果存成 dot 格式檔案,然後再利用 dot 指令轉換格式。不過它只紀錄曾經查過的名稱,開啟時重新查 cscope 而已。若圖大時,每次開啟可能會十分緩慢。

CallGraphviz 原始碼可於 github 下載,授權採用 GNU Lesser General Public License。

延伸閱讀:Python Call Graph

作者簡介

蔡志展 (Rex Tsai) 或網名 chihchun,現為自由工作者,從事開源軟體顧問或開發服務。倡議並推廣自由軟體與開放源碼,早期 KaLUG 成員,現常出席 Tossug、Hacking Thursday 聚會,亦是開源人年會(COSCUP)籌備志工。長期 Debian、OpenWrt 使用者。關注議題甚廣,進一步資訊請參考 https://people.debian.org.tw/~chihchun/




自由軟體鑄造場電子報 : 第 174 期 CallGraphviz—依據 cscope、Graphviz 以及 xdot 實作的 call graph visualizer

分類: 技術專欄



評論 

 
+1 #1 Jian 2011-06-20 06:59
Hi Rex,

thanks for the code. It's been a very helpful tool while writing my thesis.
FYI, I've forked your project on github to fulfill my requirements. Just added a button to toggle rank direction between 'LR' and 'TB', plus recursive add/delete syntax, eg. 'symbol/*' and '-symbol'

You can find it here:
github.com/.../callgraphviz