2011-03-21 19 views
64

Belirli bir işleve isabet eden tüm olası yürütme yollarını bulmak için arama grafiği oluşturmaya çalışıyorum (böylece tüm yolları manuel olarak bulmak zorunda kalmam, Bu işleve yol açan birçok yol var). Örneğin:C++ kodu için çağrı grafiği oluştur

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: ... 

ben bir şekilde her iki sonuç hedef fonksiyonunun callees başka bir şey göstermek, Codeviz ve Doxygen denedi, D. Benim durumumda, D olan nesne bir akıllı içinde sarılmış olan bir sınıfın üyesi fonksiyonudur Işaretçi. Müşteriler her zaman akıllı işaretçi nesnesini bir fabrikadan elde edebilmek için bir fabrikadan elde ederler. D.

Bunu nasıl başaracağını bilen var mı? (main dış bağlantı vardır ve bunu da çeviri birimi dışında çağrılabilir olabileceğinden, bir "dış düğüm" var)

cevap

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(); 
} 

Sonra

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

bazı parlak bir resim verir:

Callgraph

c++filt ile bunu işlemek için isteyebilirsiniz, böylece, unmangled isimleri e fonksiyonlar ve sınıflar dahil.

Beauty

mistik isimsiz fonksiyon, Node0x884c4e0, kabul bir yer tutucudur O (amanın, optimizasyonlar olmadan boyutu çok büyüktü açık!) Aşağıdaki

#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  

bu güzelliği verir olduğu gibi tanımı bilinmeyen herhangi bir işlev tarafından çağrılabilir.

+17

Şayet çok dosya proje üzerinde yapmışmıydın? Bir alet – dirvine

+0

dosyaya yerel olmayan işlevleri/birbirlerine çağrı tüm std fonksiyonları gibi dosyalar denilen olsun kalmamak için bunu yapmanın bir yolu var mı olduğu çok iyi görünüyor? – soandos

+2

+1 Herhangi bir nedenden dolayı, -n seçeneğinin, unmangle isimleri için C++ filtresine geçmek zorunda kaldım. Başka birinin aynı sorunla karşılaşması halinde burada bahsetmeyi düşündüm. 'Geçiş :: baskı değil: bu tür bilgileri bina beri – Aky

3

Kesin bir C++ çağrısı grafiğinin düzgün bir şekilde hesaplanması zordur, çünkü kesin bir langauge ayrıştırıcısına, doğru ad aramasına ve dil anlamını uygun bir şekilde onaracak iyi bir noktadan analize gereksinim duyarsınız. Doxygen bunlardan hiçbirine sahip değil, insanların neden C++ için hoşlandığını bilmediklerini bilmiyorum; Doxygen'nin hatalı olarak analiz ettiği 10 satırlık C++ örneği oluşturmak kolaydır.

timing profiler which collects a call graph dynamically'u çalıştırmaktan daha iyi olabilirsiniz (bu bizimkileri anlatıyor) ve sadece birçok durumda egzersiz yapabilirsiniz. Bu profil oluşturucular size gerçek arama grafiğini gösterir.

DÜZENLEME: Aniden arama grafiklerini oluşturduğunu iddia eden Understand for C++'u hatırladım. Bir ayrıştırıcı için ne kullandığını veya ayrıntılı analizi doğru yapıp yapmadıklarını bilmiyorum; Ürünleriyle ilgili özel bir deneyimim yok.

Schalang'ın cevabı, Clang kullanarak etkilendim; Clang'ın tüm unsurlara sahip olmasını beklerdim.

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

Ne yazık ki bu işlevi tetikleyebilir tüm kullanım durumları farkında değilim :(. Aslında, benim nihai hedefi hata ayıklama amacıyla bu işlevi kullanan kullanım durumları tam listesini bulmaktır.Doğrudan arama yapanlara kod indeksleme aracıyla ulaşabiliyorum, ancak daha fazla analiz için tüm yürütme yollarını bulmalıyım. – shiouming

3

, -### -fsyntax-only kullanılmalıdır - bscmake programı tarafından oluşturulan dosyayı okuyarak.

1

"C++ Bsc Analyzer" grafikleri çağrı gösterebilir: Tam komut olarak görünmelidir yani mpi.h iki ek seçenekler gibi standart başlık dosyaları bulmak için clang++ komut için Amacıyla

11

Sen (grafikleri nesil için noktayı kullanma seçeneğiyle) doxygen kullanarak elde edebilirsiniz.

Johannes Schaub ile

enter image description here

- main.cpp LITB, bu oluşturur:

enter image description here

doxygen/nokta muhtemelen çınlama/opt yükleyip çalıştırmak için daha kolaydır. Kendimi kurmayı başaramadım ve bu yüzden alternatif bir çözüm bulmaya çalıştım!

+1

İçerdiği pencereyi almak için doxygen'i nasıl çalıştıracağınıza bir örnek ekler misiniz? –

+0

@nimble_ninja: Ekran görüntüsü doxywizard yapılandırma iletişim kutusundan yeterli değil mi? – jpo38

+0

Bunun doxywizard'dan olduğunu bilmiyordum. Teşekkürler! –

3

Sen CppDepend kullanabilirsiniz, olabilir grafikler

  • Bağımlılık Grafik
  • Çağrı Grafik
  • Sınıf Kalıtım Grafik
  • Kavrama Grafik
  • Yol Grafik
  • Tüm Yollar birçok türde üretir Grafik
  • Döngü Grafiği

enter image description here