2011-03-21 93 views
64

我試圖產生與找出所有被擊中特定功能(這樣我就不必手動找出所有路徑的可能的執行路徑調用圖形,這有許多路徑導致這個功能)。例如:生成調用圖的C++代碼

path 1: A -> B -> C -> D 
path 2: A -> B -> X -> Y -> D 
path 3: A -> G -> M -> N -> O -> P -> S -> D 
... 
path n: ... 

我試圖Codeviz和Doxygen的,在某種程度上都表明什麼,但目標函數的被調用者,D.在我的情況下,d是一個類的成員函數,它的對象將被內部的智能包裝指針。客戶將永遠獲得通過工廠智能指針對象,以調用D.

有誰知道如何實現這一目標?

回答

95
static void D() { } 
static void Y() { D(); } 
static void X() { Y(); } 
static void C() { D(); X(); } 
static void B() { C(); } 
static void S() { D(); } 
static void P() { S(); } 
static void O() { P(); } 
static void N() { O(); } 
static void M() { N(); } 
static void G() { M(); } 
static void A() { B(); G(); } 

int main() { 
    A(); 
} 

然後

$ clang++ -S -emit-llvm main1.cpp -o - | opt -analyze -dot-callgraph 
$ dot -Tpng -ocallgraph.png callgraph.dot 

取得了一些閃亮的圖片(有一個「外部節點」,因爲main有外部鏈接,並可能從翻譯單元外也被稱爲):

Callgraph

您可能希望與c++filt進行後處理這一點,所以,你可以得到次的未重整名稱涉及的功能和類別。就像下面

#include <vector> 

struct A { 
    A(int); 
    void f(); // not defined, prevents inlining it! 
}; 

int main() { 
    std::vector<A> v; 
    v.push_back(42); 
    v[0].f(); 
} 

$ clang++ -S -emit-llvm main1.cpp -o - | 
    opt -analyze -std-link-opts -dot-callgraph 
$ cat callgraph.dot | 
    c++filt | 
    sed 's,>,\\>,g; s,-\\>,->,g; s,<,\\<,g' | 
    gawk '/external node/{id=$1} $1 != id' | 
    dot -Tpng -ocallgraph.png  

息率這個美女(噢,我的,沒有優化的大小打開是太大了!)

Beauty

那神祕的匿名函數,Node0x884c4e0,是假定一個佔位符被定義未知的任何函數調用。

+17

你有一個多文件的項目做到了這一點?看起來非常酷,作爲一個工具 – dirvine 2012-10-10 22:05:08

+0

有沒有辦法做到這一點,這樣的文件/文件不是本地的函數,如所有調用彼此的std函數不會被調用? – soandos 2013-03-15 22:06:51

+2

+1由於某些原因,我不得不將-n選項傳遞給C++ filt以取消名稱。我想在這裏提到它,以防其他人面臨同樣的問題。 – Aky 2014-01-04 10:08:21

3

靜態計算準確的C++調用圖是很難的,因爲你需要一個精確的langauge分析器,正確的名稱查找,和良好的指向的分析,妥善榮譽的語言語義。 Doxygen沒有任何這些,我不知道爲什麼人們聲稱喜歡它的C++;很容易構建Doxygen錯誤分析的10行C++示例)。

你可能會更好運行timing profiler which collects a call graph dynamically(這說明我們的),只是行使了很多案例。這些分析器將向您顯示實際的調用圖。

編輯:我突然想起Understand for C++,號稱構建調用圖。我不知道他們用於解析器,或者他們是否做了詳細的分析;我對他們的產品沒有具體的經驗。

Schaub的回答給我留下了深刻的印象,使用了Clang;我希望Clang擁有所有的元素。

+0

不幸的是,我不知道所有可能觸發該功能的用例:(實際上,我的最終目標是找出使用該函數進行調試的用例的確切列表。我可以通過代碼索引工具找到直接調用者,但需要找出所有執行路徑以供進一步分析。 – shiouming 2011-03-21 10:40:45

3

爲了使clang++命令查找標準頭文件等mpi.h兩個附加選項應使用-### -fsyntax-only,即完整的命令應該看:

clang++ -### -fsyntax-only -S -emit-llvm main1.cpp -o - | opt -analyze -dot-callgraph 
1

中的「C++理學士分析器」可以顯示調用圖 - 通過讀取bscmake實用程序生成的文件。

11

您可以通過使用doxygen(使用點生成圖表選項)來實現。

enter image description here

隨着約翰內斯·紹布 - litb main.cpp中,它會產生這樣的:

enter image description here

的doxygen /點可能比鐺/ opt下安裝和運行更加容易。我沒有設法自己安裝它,這就是爲什麼我試圖尋找替代解決方案!

+1

您可以添加一個如何運行doxygen以獲取您包含的窗口的示例嗎? – 2017-03-07 23:21:59

+0

@nimble_ninja:doxywizard配置對話框的屏幕截圖不夠嗎? – jpo38 2017-03-08 06:20:00

+0

我不知道它來自doxywizard。謝謝! – 2017-03-08 12:18:25

3

您可以使用CppDepend,它可以產生多種圖形

  • 依賴圖
  • 調用圖形
  • 類繼承圖
  • 耦合圖
  • 路徑圖
  • 所有路徑圖表
  • 循環圖

enter image description here