2017-01-06 16 views
1

我想用C++寫的一些庫代碼進行修補。一個相當複雜的應用程序位於庫的頂部。爲了修補代碼,我經常需要了解在整個代碼庫中如何使用庫函數,並確保我不會破壞任何下游客戶端。生成所有可能的呼叫樹堆

假設foo()從我的媒體庫的DLL導出。在客戶端代碼中,bar()調用foo()baz()調用bar()。我需要確保barbaz都可以在我的更改後生效。在我的情況下,調用堆棧實際上很深,並且不容易手動跟蹤,因爲沒有一個調用堆棧,我的庫函數可以在調用堆棧的頂部登陸很多方法。

使用Visual Studio或g ++或clang,有沒有一種方法可以生成一個樹,使得我的庫函數位於根,而分支是我函數可以放置在頂部的所有各種方式調用堆棧?我的意思是這種功能已經存在於其中一種流行的工具鏈中嗎?如果沒有,你知道有其他方式來生成這樣一棵樹嗎?

回答

1

我不認爲任何一個編譯器有選擇生成此信息。

在一般情況下,有很多幹擾因素,這將使這個非常困難的:

  • 如果有遞歸的代碼,那麼你想要的樹實際上是一個曲線圖/網絡循環。

  • 虛方法,函數指針和成員函數指針可能使這個停機問題的等價物。如果你有兩個具體的類A和共享公共基類,它提供的虛擬方法foo()B,那麼你就必須做詳盡的分析,以確定通過指針或引用基類的foo()特定呼叫是否應算作作爲致電A::foo()B::foo()或兩者。同樣適用於各種風味的函數指針。

  • 如果你依賴於系統或其他能夠回調到你的代碼的第三方庫,你最好有它們的源代碼。例如,Windows GUI程序通常具有從系統代碼調用的窗口過程,可能是響應您的代碼到系統中的調用。由於您不會擁有Windows資源,因此您必須假設您可以隨時調用任何和所有回調函數,因此您的「樹」將具有許多根源。

應對這種現代的方式是不分析你的庫可以被稱爲所有的方法,但要記錄它應該叫的所有方式。構建一個測試套件,以您想要支持的所有合理方式調用庫。然後,你可以修補,然後運行你的測試套件,看看你是否打破了圖書館的合同。如果在集成測試中發現圖書館的客戶端由於您的更改而中斷,則表示測試套件不完整,或者客戶端以不受支持的方式調用圖書館。