[英]static analysis checks fails to find trivial C++ issue
我在我們的 C++ Static 分析工具中遇到了令人驚訝的假陰性。
我們使用 Klocwork(目前 2021.1),
幾位同事報告發現了 KW 應該發現的問題。
我把例子簡化為:
int theIndex = 40;
int main()
{
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
return arr[theIndex];
}
任何業余愛好者都可以看到我肯定正在訪問數組 [0..9] 的綁定數組成員 [40]。
但是 KW 沒有報告那個明顯的缺陷!
TBH,我也使用了 CppCheck 和 SonarQube,但它們也失敗了!
測試更直接的流程,例如:
int main()
{
int theIndex = 40;
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
return arr[theIndex];
}
確實找到了豐富的問題。
我的猜測是 KW 沒有將main()
視為入口點,因此假設theIndex
在調用之前可能會更改。
我也厭倦了一個“可能工作”的版本(如果有另一個任務可以完美同步)
int theIndex;
int foo() {
const int arr[10] = {0,1,2,3,4,5,6,7,8,9};
return arr[theIndex];
}
int main()
{
theIndex = 40;
return foo();
}
CppCheck 發現它“沒有錯誤”。
我的問題是:
編輯:
正如@RichardCritten 假設 SA 工具實現其他編譯單元可以更改theIndex
的值因此並不表示問題。
這適用於聲明static int theIndex = 40
表明了問題。
現在我想知道:
KW 獲得了完整的構建規范,
因此從理論上講,該工具可以跟蹤軟件的所有分支並跟蹤theIndex
的可能值(可能是計算限制)。
我的猜測是 KW 沒有將 main() 視為入口點,因此假設 theIndex 在調用之前可能會更改。
theIndex
實際上可以在輸入main
之前更改。 程序中任何地方的全局變量的每個初始值設定項都可以執行任意代碼並訪問所有全局變量。 因此,如果假設在輸入main
之前全局變量的所有初始值保持不變,該工具可能會產生大量誤報。
當然,這並不意味着該工具無法決定發出警告,冒着誤報的風險。 我不知道所提到的工具是否可以配置為這樣做。
如果這是一個常量,則將其標記為constexpr
。 然后我希望工具能夠識別這個問題。
如果它不應該是常量,請嘗試擺脫它。 不是常量的全局變量會導致很多問題。 因為它們可能會被調用主體未知的 function 所修改(並且在進入main
線程或線程之前),所以對於人類、static 分析器和優化器來說,它們很難跟蹤。
給變量內部鏈接可以簡化分析,因為該工具可以證明給定翻譯單元中的任何內容都不能從另一個翻譯單元訪問以設置變量的值。 如果有類似的東西,那么另一個單元中的全局初始化器可能仍然會在進入main
之前修改它。 如果不是這種情況,並且變量的翻譯單元中也沒有全局初始化器修改它,那么該工具可以確保該值在main
之前保持不變。
使用外部鏈接不起作用,因為任何翻譯單元都可以通過聲明它來訪問變量。
從技術上講,我認為一個足夠復雜的工具可以進行整個程序分析,以驗證全局變量是否在main
之前被修改。 但是,如果涉及動態庫,這在理論上已經存在問題,我認為這不是 static 分析器采用的典型方法。 (我在這一點上可能是錯的。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.