說來真是慚愧呀.一直在用VIM 作開發.殊不知道VI 裏還有這麼好使的工具.之前一直都是用:php
find -type f -print | xargs grep -i **** 在源代碼裏查找.html
原來Linux下也有相似於Souce Insight工具.如下是引用人家的文章.http://blog.chinaunix.net/u1/56619/showart_1822993.html前端
linux源代碼分析和閱讀工具比較linux
Windows下的源碼閱讀工具Souce Insight 憑 藉着其易用性和多種編程語言的支持,無疑是這個領域的「帶頭大哥」。Linux/UNIX環境下呢?彷佛仍然是處於百花齊放,各有千秋的春秋戰國時代,實 際上,彷佛其環境下的任何軟件都是處於一種逐鹿中原的態勢,也許這就是「集市」之於「大教堂」的優點所在吧!主要的交叉索引工具備:ctags 、 cscope 、 global 、 lxr 、 KScope 、 sourcenav 、 calltree 、 CodeViz 、ncc 、gprof 等。 下面將就各軟件的優劣做一簡單介紹。這裏面當中,我當前分析過他們的源碼的有lxr、sourcenav、calltree、ncc。如今正在 sourcenav的基礎上進行我須要的改造以更合適分析內核須要。KScope須要進一部考察和分析,若是KScope的代碼分析能力(也就是 scope的能力)跟得上sourcenav可能到時會放棄sourcenav轉到KScope開發,由於sourcenav的界面和交互性都不怎麼好。c++
ctags應該是幾個裏面最古老的一個了,固然也是得到支持最多的一個,vim默認就支持ctags產生的tag數據庫,不過原來的ctags名符其實, 只支持C語言,且分析不夠細膩。其新版本名爲exuberant ctags,可是它已經遠遠超出了它名字的範疇,支持包括C語言在內的33種編程語言,準確度上也不錯,而且它的開發仍在如火如荼地進行着,前途無量啊!
配合vim使用,基本上能知足用戶的要求。
經常使用命令:
創建數據庫命令:web
exuberant-ctags數據庫
在vim編輯器中瀏覽:編程
:ta x 跳轉到符號x的定義處,若是有多個符號,直接跳轉到第一處 :ts x 列出符號x的定義 :tj x 能夠看作上面兩個命令的合併,若是隻找到一個符號定義,那麼直接跳轉到符號定義處,若是有多個,則讓用戶自行選擇。 Ctrl+] 跳轉到當前光標下符號的定義處,和ta相似。 Ctrl+t 跳轉到上一個符號定義處,和上面的配合基本上就能自由跳轉了。 另外兩個:tn, :tp是在符號的多個定義之間跳轉 |
美中不足,只能查找符號的定義,不能實現交叉引用查詢等其它功能。vim
相比ctags的只能查找符號的定義,cscope則顯得更加豐富,雖然他支持C語言,可是它除了能查找函數的定義,還能查找函數在哪裏被調用過等,因此能在必定程度上彌補ctags的不足。
經常使用命令:
創建數據庫的命令:windows
cscope和vim配合使用:
再也不重複vim文檔了,本身經過命令
:help cscope
去詳細學習吧。
比較遺憾的是,cscope的最後一次更新是在2003年,這個項目彷佛也是被人拋棄了,但願之後能被人收養,或者和其它項目合併。
Global是GNU出品的交叉索引工具,支持C, C++, Yacc, Java 和PHP4五種語言,命令行下表現不錯,可是和vim配合使用,就不如前面兩個更加親切了。其特點在於分析得很細膩,我所研究過的,暫時只能 soucenav能超過它。能生成交叉索引的web頁,很適合用來作程序的文檔。數據庫是從berkeley BD 3上改過來的。但和個人要需求卻有比較大的差距。由於它只有一個WEB的前端,在功能上,他現有的前端也只實現符號查詢和交叉引用查詢。
Linux超文本交叉代碼檢索工具LXR(Linux Cross Reference),是由挪威奧斯陸大學數學系Arne Georg Gleditsch和Per Kristian Gjermshus編寫的。這個工具實際上運行在Linux或者Unix平臺下,經過對源代碼中的全部符號創建索引,從而能夠方便的檢索任何一個符號,包 括函數、外部變量、文件名、宏定義等等。不只僅是針對Linux源代碼,對於C語言的其餘大型的項目,均可以創建其lxr站點,以提供開發者查詢代碼,以 及後繼開發者學習代碼。
目前的lxr是專門爲Linux下面的Apache服務器設計的,經過運行perl腳本,檢索源代碼索引文件,將數據發送到網絡客戶端的Web瀏覽器上。 任何一種平臺上的Web瀏覽器均可以訪問,這就方便了習慣在Windows平臺下工做的用戶。 關於lxr的英文網站爲http://lxr.linux.no/ ,在中國Linux論壇http://www.linuxforum.net 上有其鏡象。
好的說完了。說說缺點,可能我分析得不深刻,它的代碼不是用C寫的,是網頁腳本,程序也很短,沒有看到有應用數據庫。不少的東西都是你瀏覽的時候才生成的,因此拿過來用或改造的潛力有限,並且代碼分析的不夠Global細膩。
KScope是cscope的圖形前端,他爲那些不熟悉vim或者是不習慣終端做業的人提供了圖形界面的選擇,界面是這一款軟件的一個亮點,比 source insight還好看,從windows轉過來作Linux開發的人可能感受比較親切。這也是我最近動心的緣由。另外,它還有個比較迷人的特色:能生成函 數調用樹。但說百了,實際上是調用graphviz畫出來的。
snavigator是一個不錯的源代碼編輯和項目管理軟件。有Windows和Linux版本。網址http://sourceforge.net/projects/sourcenav 。
基本介紹:Source-Navigator is a source code analysis tool. With it, you can edit your source code, display relationships between classes and functions and members, and display call trees.
這種工具號稱是source insight是linux對手,和確,通過我這一輪的GOOGLE後,從分析性能上,只有他和source insight的能平行的。但可操做性方面就遠遠沒有source insight強了,不少功能用起來都沒有source insight順心。界面就比kScope差很遠了,這也就是我對KScope心動的緣由。和source insight比,還有一點不行的就是,需然生成交叉引用是在後臺進行了,但它是一次性連續生成的,而source insight生成是,則更爲優先生成客戶當前的代碼,source insight這一點對客戶的考慮真不錯。數據庫方面採用的也是berkeley BD 4,他和Global同樣,在數據庫的使用方面,第個表只採用了兩個字端,KEY和DATA,也就是說沒采用Secondary Databases,這致使不少時候都是把所有的記錄返回,而後再優程序來篩選,這種方式把數據庫的優勢全給埋沒了,要知道對linux這類原碼,交叉引 用數據庫可能達幾百M,這麼幹內存也不夠,速度也更不用談。我尚未研究KScope不知它在這方面怎麼樣,我以爲sourcenav這方面確定要改掉。 把數據篩選的工做徹底由數據庫來作,他們會作得很好。
可開發性方面,sourcenav作得還算不錯,有用戶文檔和開發文檔,代碼結構也比較可能,TCL編程也直對比較容易。能夠在它原來功能的基礎上進行功能擴充。接下來的幾編BLOG,我會對它的源碼進行分析。
除了上述的體系比較完整的工具外,還有不少源源分析的小工具。這些小工具多數是用來繪製函數調用關係圖的。
繪製函數調用關係圖對理解大型程序大有幫助。我想你們都有過一邊讀源碼(並在頭腦中維護一個調用棧),一邊在紙上畫函數調用關係,而後整理成圖的經歷。如 果運氣好一點,藉助調試器的單步跟蹤功能和call stack窗口,能節約一些腦力。不過若是要分析的是腳本語言的代碼,那多半隻好老老實實用第一種方法了。若是在讀代碼以前,手邊就有一份調用圖,豈不妙 哉?下面舉出我知道的幾種免費的分析C/C++函數調用關係的工具。
函數調用關係圖(call graph)是圖(graph),並且是有向圖,多半仍是無環圖(無圈圖)——若是代碼中沒有直接或間接的遞歸的話。Graphviz 是專門繪製有向圖和無向圖的工具,因此不少call graph分析工具都以它爲後端(back end)。那麼前端呢?就看各家各顯神通了。
調用圖的分析分析大體可分爲「靜態」和「動態」兩種,所謂靜態分析是指在不運行待分析的程序的前提下進行分析,那麼動態分析天然就是記錄程序實際運行時的函數調用狀況了。
靜態分析又有兩種方法,一是分析源碼,二是分析編譯後的目標文件。
分析源碼得到的調用圖的質量取決於分析工具對編程語言的理解程度,好比能不能找出正確的C++重載函數。Doxygen 是源碼文檔化工具,也能繪製調用圖,它彷佛是本身分析源碼得到函數調用關係的。GNU cflow也是相似的工具,不過它彷佛偏重分析流程圖(flowchart)。
對編程語言的理解程度最好的固然是編譯器了,因此有人想出給編譯器打補丁,讓它在編譯時順便記錄函數調用關係。CodeViz (其靈感來自Martin Devera (Devik) 的工具 )就屬於此類,它(1.0.9版)給GCC 3.4.1打了個補丁。另一個工具egypt 的思路更巧妙,不用大動干戈地給編譯器打補丁,而是讓編譯器本身dump出調用關係,而後分析分析,交給Graphviz去繪圖。不過也有人另起爐竈,本身寫個C語言編譯器(ncc ),專門分析調用圖,勇氣可嘉。不如要是對C++語言也這麼幹,成本難免過高了。分析C++的調用圖,仍是藉助編譯器比較實在。
分析目標文件聽起來挺高深,其實否則,反彙編的工做交給binutils的objdump去作,只要分析一下反彙編出來的文本文件就好了。下面是Cygwin下objdump -d a.exe的部分結果:
00401050 <_main>:
401050: 55 push %ebp
401051: 89 e5 mov %esp,%ebp
401053: 83 ec 18 sub $0x18,%esp
......
40107a: c7 44 24 04 00 20 40 movl $0x402000,0x4(%esp)
401081: &n
401082: c7 04 24 02 20 40 00 movl $0x402002,(%esp)
401089: e8 f2 00 00 00 call 401180 <_fopen>
從中能夠看出,main()調用了fopen()。CodeViz帶有分析目標文件的功能。
動態分析是在程序運行時記錄函數的調用,而後整理成調用圖。與靜態分析相比,它能得到更多的信息,好比函數調用的前後順序和次數;不過也有必定的缺點,好比程序中語句的某些分支可能沒有執行到,這些分支中調用的函數天然就沒有記錄下來。
動態分析也有兩種方法,一是藉助gprof的call graph功能(參數-q),二是利用GCC的 -finstrument-functions
參數。
gprof生成的輸出以下:
index % time self children called name
0.00 0.00 4/4 foo [4]
[3] 0.0 0.00 0.00 4 bar [3]
-----------------------------------------------
0.00 0.00 1/2 init [5]
0.00 0.00 1/2 main [45]
[4] 0.0 0.00 0.00 2 foo [4]
0.00 0.00 4/4 bar [3]
-----------------------------------------------
0.00 0.00 1/1 main [45]
[5] 0.0 0.00 0.00 1 init [5]
0.00 0.00 1/2 foo [4]
-----------------------------------------------
從中能夠看出,bar()被foo()調用了4次,foo()被init()和main()各調用了一次,init()被main()調用了一次。用 Perl腳本分析gprof的輸出,生成Graphviz的dot輸入,就能繪製call graph了。這樣的腳本不止一我的寫過:http://www.graphviz.org/Resources.php ,http://www.ioplex.com/~miallen/ 。
GCC的-finstrument-functions 參數的做用是在程序中加入hook,讓它在每次進入和退出函數的時候分別調用下面這兩個函數:
void __cyg_profile_func_enter( void *func_address, void *call_site )
__attribute__ ((no_instrument_function));
void __cyg_profile_func_exit ( void *func_address, void *call_site )
__attribute__ ((no_instrument_function));
固然,這兩個函數自己不能被鉤住(使用no_instrument_function這個__attribute__),否則就反反覆覆萬世不竭了:) 這裏得到的是函數地址,須要用binutils中的addr2line這個小工具轉換爲函數名,若是是C++函數,還要用c++filt進行name demangle。具體方法在《用Graphviz 可視化函數調用 》中有詳細介紹,這裏再也不贅述。
從適應能力上看,源碼分析法是最強的,即使源碼中有語法錯,頭文件不全也不要緊,它照樣能分析個八九不離十。而基於編譯器的分析法對源碼的要求要高一些, 至 少能編譯經過(gcc 參數 -c)——能產生object file,不必定要連接獲得可執行文件。這至少要求源碼沒有語法錯,其中調用的函數不必定有定義(definition),但要有聲明 (declaration),也就是說頭文件要齊全。固然,真的不全也不要緊,本身放幾個函數聲明在前面就能糊弄編譯器:) 至於動態分析,要求最高——程序需得運行起來。若是你要分析的是操做系統中某一部分,好比內存管理或網絡協議棧,那麼這裏提到的兩種動態分析法恐怕都不適 用了。
[1] 使用Gnu gprof進行Linux平臺下的程序分析
[2] The DOT Language
http://www.graphviz.org/doc/info/lang.html
[3] Graphviz - Graph Visualization Software
http://www.graphviz.org/
[4] Coverage Measurement and Profiling
http://www.linuxjournal.com/article/6758
[5] 用Graphviz進行可視化操做──繪製函數調用關係圖
[6] cscope
http://cscope.sourceforge.net/
[7] KFT(Kernel Function Tracing)
http://elinux.org/Kernel_Function_Trace
ftp://dslab.lzu.edu.cn/pub/kft
[8] Call Graph -- Gprof
http://sourceware.org/binutils/docs-2.17/gprof/Call-Graph.html#Call-Graph
[9] 各種分析函數調用關係圖的工具 http://oss.lzu.edu.cn/blog/blog.php?do_showone/tid_1636.html