靜態分析C語言生成函式呼叫關係的利器——cflow
阿新 • • 發佈:2018-12-19
除了《靜態分析C語言生成函式呼叫關係的利器——calltree》一文中介紹的calltree,我們還可以藉助cflow輔助我們閱讀理解程式碼。(轉載請指明出於breaksoftware的csdn部落格)
cflow的說明和安裝
cflow是一款靜態分析C語言程式碼的工具,通過它可以生成函式的呼叫關係。和calltree不一樣,cflow有獨立的網頁介紹它(https://www.gnu.org/software/cflow/#TOCdocumentation)。而且在Ubuntu系統上,我們可以不用去編譯cflow的原始碼,而直接使用下面命令獲取
apt-get install cflow
cflow的使用
安裝完畢,我們可以使用下面指令看到cflow的引數說明
cflow --help
我們可以得到如下提示
Usage: cflow [OPTION...] [FILE]...
generate a program flowgraph
General options:
-d, --depth=NUMBER Set the depth at which the flowgraph is cut off
-f, --format=NAME Use given output format NAME. Valid names are
`gnu' (default) and `posix'
-i, --include=CLASSES Include specified classes of symbols (see below).
Prepend CLASSES with ^ or - to exclude them from
the output
-o, --output=FILE Set output file name (default -, meaning stdout)
-r, --reverse * Print reverse call tree
-x, --xref Produce cross-reference listing only
Symbols classes for --include argument
_ symbols whose names begin with an underscore
s static symbols
t typedefs (for cross-references only)
x all data symbols, both external and static
Parser control:
-a, --ansi * Accept only sources in ANSI C
-D, --define=NAME[=DEFN] Predefine NAME as a macro
-I, --include-dir=DIR Add the directory DIR to the list of directories
to be searched for header files.
-m, --main=NAME Assume main function to be called NAME
-p, --pushdown=NUMBER Set initial token stack size to NUMBER
--preprocess[=COMMAND], --cpp[=COMMAND]
* Run the specified preprocessor command
-s, --symbol=SYMBOL:[=]TYPE Register SYMBOL with given TYPE, or define an
alias (if := is used). Valid types are: keyword
(or kw), modifier, qualifier, identifier, type,
wrapper. Any unambiguous abbreviation of the above
is also accepted
-S, --use-indentation * Rely on indentation
-U, --undefine=NAME Cancel any previous definition of NAME
Output control:
-b, --brief * Brief output
--emacs * Additionally format output for use with GNU
Emacs
-l, --print-level * Print nesting level along with the call tree
--level-indent=ELEMENT Control graph appearance
-n, --number * Print line numbers
--omit-arguments * Do not print argument lists in function
declarations
--omit-symbol-names * Do not print symbol names in declaration strings
-T, --tree * Draw ASCII art tree
Informational options:
--debug[=NUMBER] Set debugging level
-v, --verbose * Verbose error diagnostics
-?, --help give this help list
--usage give a short usage message
-V, --version print program version
Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.
* The effect of each option marked with an asterisk is reversed if the option's
long name is prefixed with `no-'. For example, --no-cpp cancels --cpp.
Report bugs to < [email protected]>.
我只列出我覺得有意思的幾個引數:
-T輸出函式呼叫樹狀圖
-m指定需要分析的函式名
-n輸出函式所在行號
-r輸出呼叫的反向關係圖
--cpp預處理,這個還是很重要的
文字輸出
最簡單的使用方法是以ASCII文字的方式輸出結果,比如
cflow -T -m main -n timer.c
其結果是一個包含檔名和函式所在程式碼行號的呼叫關係圖
+-main() <int main (void) at timer.c:13>
+-ev_timer_init()
+-timeout_cb() <void timeout_cb (EV_P_ ev_timer *w, int revents) at timer.c:7>
| +-puts()
| \-ev_break()
+-ev_timer_start()
\-ev_run()
然而,對於有一定程式碼量的專案,我們不會使用ASCII文字的方式去檢視函式呼叫關係,因為呼叫是相當複雜的,而文字圖並不適合人去理解。於是我們希望能cflow能產出一個可供其他軟體轉換成圖片的格式的檔案。可惜cflow並不支援,好在網上有開發者做了一個工具,可將其結果轉換成dot格式。
轉成dot檔案
我們可以使用下面方法獲取轉換工具wget -c https://github.com/tinyclub/linux-0.11-lab/raw/master/tools/tree2dotx
下載完tree2dotx後,可對其做個軟鏈便於使用
cd /usr/bin
ln -s 【Your Path】/tree2dotx tree2dotx
具體的轉換方法是
cflow -T -m main -n timer.c > main.txt
cat main.txt | tree2dotx > main.dot
dot檔案生成圖片
我們需要藉助graphviz(沒有安裝的可以使用apt-get install graphviz先安裝)生成圖片,指令是
dot -Tgif main.dot -o main.gif