最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

程序人生:讀開源項(xiàng)目需謹(jǐn)慎!盤點(diǎn)C++開源項(xiàng)目中的十大BUG

2020-10-30 22:41 作者:C語言編程__Plus  | 我要投稿

又一年即將結(jié)束,是時(shí)候盤點(diǎn)一下開源項(xiàng)目中的 Bug 了。2020 年的盤點(diǎn)可能還需要點(diǎn)時(shí)間,本文我們先來看看 2019 年開源 C/C++ 項(xiàng)目中遇到的一些最有趣的槽點(diǎn)。


No. 10. 我們正運(yùn)行在什么操作系統(tǒng)上?

V1040 可能拼寫錯(cuò)誤預(yù)定義宏名稱?!?strong>MINGW32_‘有點(diǎn)兒像’MINGW32__’。winapi.h 4112


MINGW32_ 宏的名稱拼寫有誤(MINGW32 實(shí)際上被聲明為MINGW32__)。在項(xiàng)目的其它地方,拼寫是正確的:


順便說一句,這個(gè) bug 并不是在文章"CMake: the Case when the Project’s Quality is Unforgivable"中首次被描述,而是在一個(gè)開源項(xiàng)目的 V1040 診斷中就真正被第一次發(fā)現(xiàn)的 bug(2019 年 8 月 19 日)。

https://www.viva64.com/en/b/0658/?ref=hackernoon.com


No. 9. 哪個(gè)先?

V502 可能’?:‘運(yùn)算符的工作方式與預(yù)期不符?!?:‘運(yùn)算符的優(yōu)先級比’=='運(yùn)算符低。mir_parser.cpp 884


我們感興趣的下面的部分:


'=='運(yùn)算符的優(yōu)先級比三元運(yùn)算符 (?:) 高。因此,這個(gè)條件表達(dá)式的求值順序錯(cuò)誤,等效于如下代碼:


由于常量 OP_intrinsiccall 和 OP_intrinsiccallassigned 都是非 null 的,這個(gè)條件會一直返回 true,這意味著 else 分支是無法訪問的代碼。

這個(gè) bug 在文章"Checking the Ark Compiler Recently Made Open-Source by Huawei"中被提到。

https://www.viva64.com/en/b/0690/?ref=hackernoon.com


No. 8. 危險(xiǎn)的位運(yùn)算符

V1046 在位運(yùn)算符’&='中不安全地使用’bool’和’int’類型。GSLMultiRootFinder.h 175


代碼建議 SetFunctionList 函數(shù)遍歷一個(gè)迭代器列表。如果至少有一個(gè)迭代器是無效的,這個(gè)函數(shù)會返回 false,否則就返回 true。

然而,SetFunctionList 函數(shù)對于有效的迭代器也會返回 false。讓我們來看看是為什么。AddFunction 函數(shù)返回 fFunctions 列表中有效迭代器的數(shù)目。也就是說,添加非空迭代器將導(dǎo)致列表的大小遞增:1、2、3、4,以此類推。這就是 bug 生效的地方:

ret &= AddFunction(*f);

由于這個(gè)函數(shù)返回一個(gè) int 類型的值而不是 bool 類型,因此對于偶數(shù)值’&='運(yùn)算符也會返回 false,因?yàn)榕紨?shù)的最低有效位始終設(shè)置為 0。這就是為什么一個(gè)微小的 bug 會打破 SetFunctionsList 的返回值,即使它的參數(shù)是有效的。

如果你仔細(xì)閱讀了代碼片段(你是認(rèn)真的,對吧?),你可能已經(jīng)發(fā)現(xiàn),它來自 ROOT 項(xiàng)目。是的,我們也發(fā)現(xiàn)了這個(gè) bug:“Analyzing the Code of ROOT, Scientific Data Analysis Framework”。

https://www.viva64.com/en/b/0682/?ref=hackernoon.com


No. 7. 變量混淆

V1001[CWE-563] 'Mode’變量被賦值了,但是直到函數(shù)結(jié)束都沒有被使用。SIModeRegister.cpp 48


對函數(shù)參數(shù)和類成員使用相同的名字是非常危險(xiǎn)的,因?yàn)槟愫芸赡馨阉鼈兓煜6@里就是這樣的。下面的表達(dá)式?jīng)]有意義:

Mode&= Mask;

函數(shù)的參數(shù)變化之后,這個(gè)參數(shù)之后不會以任何形式被使用。編程人員很可能想要寫的是:


這個(gè) bug 在 LLVM 發(fā)現(xiàn)。我們有一個(gè)傳統(tǒng),不時(shí)地檢查這個(gè)項(xiàng)目。今年我們又 檢查了一次這個(gè)項(xiàng)目。


No. 6. C++ 有自己的的規(guī)則

這個(gè) bug 源于 C++ 規(guī)則并不總是遵循數(shù)學(xué)規(guī)則或“常識”??纯聪旅娴拇a片段,試著自己找出 bug 吧。

V709 發(fā)現(xiàn)的可疑比較:‘f0 == f1 == m_fractureBodies.size()’。記住, ‘a(chǎn) == b == c’并不等價(jià)于’a == b && b == c’。


這個(gè)條件表達(dá)式似乎是在檢查 f0 等于 f1,并且等于 m_fractureBodies 中元素的數(shù)目。這可能意味著,檢查 f0 和 f1 是否位于 m_fractureBodies 數(shù)組的末尾,因?yàn)樗鼈兌及?findLinearSearch() 方法發(fā)現(xiàn)的一個(gè)對象。但實(shí)際上,這個(gè)條件表達(dá)式檢查 f0 是否等于 f1,然后檢查 m_fractureBodies.size() 是否等于 f0 == f1 表達(dá)式的結(jié)果。也就是說,這里第三個(gè)運(yùn)算數(shù)是 0 或 1。

這是一個(gè)好 bug!而且,幸運(yùn)的是,這個(gè) bug 非常罕見。到目前為止,我們只在 3 個(gè)開源項(xiàng)目中看到過這個(gè) bug,而且有趣的是,這 3 個(gè)項(xiàng)目都是游戲引擎。這不是 Bullet 中發(fā)現(xiàn)的唯一 bug;最有趣的一些 bug 在文章"PVS-Studio Looked into the Red Dead Redemption’s Bullet Engine"有描述。

https://www.viva64.com/en/b/0647/?ref=hackernoon.com


No. 5. 行末尾是什么?

這個(gè) bug 很容易發(fā)現(xiàn),如果你知道其中細(xì)節(jié)的話。

V739 EOF 不應(yīng)該與一個(gè)’char’類型的值進(jìn)行比較。'ch’應(yīng)該是’int’類型。json.cpp 762


這是你很難發(fā)現(xiàn)的一些 bugs 之一,如果你不知道 EOF 是被定義為 -1 的話。因此,如果你試圖將它與一個(gè)帶標(biāo)志的字符類型變量比較時(shí),條件表達(dá)式的結(jié)果幾乎總會是 false。唯一的例外是編碼為 0xFF(255) 的字符。當(dāng)與 EOF 比較時(shí),這個(gè)字符會變成 -1,因此會讓這個(gè)條件表達(dá)式的結(jié)果為 true。

在這幾年的眾多 bugs 中,前 10 名都是在計(jì)算機(jī)游戲軟件中發(fā)現(xiàn)的:引擎或開源游戲。你可能已經(jīng)猜到了,這個(gè) bug 也是來自游戲領(lǐng)域。更多錯(cuò)誤在"Cataclysm Dark Days Ahead: Static Analysis and Roguelike Games"一文中有描述。

https://www.viva64.com/en/b/0628/?ref=hackernoon.com


No. 4. 常量 Pi

V624 對于’3.141592538’常量可能有錯(cuò)誤打印??紤]使用 <math.h> 中的 M_PI 常量。PhysicsClientC_API.cpp 4109


在 Pi 數(shù)字 (3,141592653…) 中有一個(gè)微小的打印錯(cuò)誤:第 7 個(gè)小數(shù)位的數(shù)字“6”丟失了。


一個(gè)不正確的百萬分之一的小數(shù)位很難造成任何明顯的損害,但是最好使用庫里已有的常量,其正確性有所保障。例如,Pi 數(shù)字由頭文件 math.h 中的 M_PI 常量表示。

你可能在文章"PVS-Studio Looked into the Red Dead Redemption’s Bullet Engine"中已經(jīng)讀到過這個(gè) bug,它在其中排第 6 位。如果你還沒讀到過,這次可別錯(cuò)過。

https://www.viva64.com/en/b/0647/?ref=hackernoon.com


No. 3. 難以捉摸的異常

V702std::exception(以及類似的)中的類應(yīng)該是’public’的(沒有指定關(guān)鍵字的話,編譯器默認(rèn)是’private’的)。CalcManager CalcException.h 4


分析器檢測到來自 std::exception 的一個(gè)類使用了 private 修飾符(如果沒有指定的話默認(rèn)使用 private)。這段代碼的問題是,試圖捕獲一個(gè)通用的 std::exception 將會導(dǎo)致這個(gè)程序錯(cuò)過 CalcException 類型的異常。這個(gè)行為源于 private 繼承禁止隱式類型轉(zhuǎn)換。

你肯定不希望看到你的程序因?yàn)橐粋€(gè)漏掉的 public 修飾符而崩潰。順便說一句,我打賭你在一生中肯定至少用過這個(gè)應(yīng)用程序一次,因?yàn)樗褪抢系?Windows Calculator,我們早幾年也檢查過這個(gè)應(yīng)用程序。


No. 2. 未閉合的 HTML 標(biāo)簽

V735 可能是一個(gè)不正確的 HTML。碰到"“閉合標(biāo)簽時(shí),預(yù)期的是”" 標(biāo)簽。book.cpp 127


由于它經(jīng)常發(fā)生,C/C++ 源代碼本身沒有太多說明,因此讓我們看看上面的代碼片段生成的預(yù)處理代碼:


分析器發(fā)現(xiàn)了一個(gè)未閉合的 div 標(biāo)簽。這里有很多 html 代碼片段,因此作者需要修改代碼。

很驚訝我們能診斷出這種類型的 bugs 嗎?我第一次看到這一點(diǎn)時(shí),印象也非常深刻。因此,是的,我們確實(shí)知道一些關(guān)于分析 html 代碼的知識。不過,只在 C++ 代碼中才行。:)

不僅這個(gè) bug 被排在第二位,這也是我們的前 10 榜單中的第二個(gè)計(jì)算器。可以閱讀"Following in the Footsteps of Calculators: SpeedCrunch"這篇文章,來看看我們在這個(gè)項(xiàng)目發(fā)現(xiàn)的其它 bugs。

https://www.viva64.com/en/b/0618/?ref=hackernoon.com


No. 1. 難以捉摸的標(biāo)準(zhǔn)函數(shù)

這個(gè) bug 位于第一位,是一種非常奇怪的 bug,能夠成功通過代碼評審。

你自己試試發(fā)現(xiàn)這個(gè) bug:


現(xiàn)在讓我們看看分析器怎么說:

V560 部分條件表達(dá)式總是 true:(’\n’ != c)。params.c 136.

很奇怪,對不對?讓我們看看在另一個(gè)文件(charset.h)中其它奇怪的點(diǎn):


嗯,這確實(shí)很奇怪… 因此,如果變量 c 等于’\n’,那么看起來無害的函數(shù) isspace? 會返回 false,從而因?yàn)槎搪愤壿嫸粓?zhí)行第二部分的檢查。而且如果 isspace? 執(zhí)行,變量 c 將會等于 ‘’ 或’\t’,明顯不會等于’\n’。

你可能會說,這個(gè)宏與 #define true false 類似,像這樣的代碼永遠(yuǎn)不能通過一個(gè)代碼評審。但是這個(gè)特殊的代碼片段確實(shí)通過了代碼評審——而且還在代碼庫中等待被發(fā)現(xiàn)。

有關(guān)這個(gè) bug 的更詳細(xì)的評論,請查看文章"Wanna Play a Detective? Find the Bug in a Function from Midnight Commander"。

https://www.viva64.com/en/b/0610/


結(jié) 論


我們發(fā)現(xiàn)的這些 Bug 都是一些常見的復(fù)制 - 粘貼錯(cuò)誤、不準(zhǔn)確的常量、未閉合的標(biāo)簽以及許多其它缺陷。但是我們的分析器正在不斷演進(jìn)和 學(xué)習(xí) 來診斷越來越多類型的問題,因此我們肯定不會放慢腳步,并且會像以前一樣定期發(fā)布關(guān)于項(xiàng)目中發(fā)現(xiàn)的 bugs 的新文章。

作者介紹:

PVS-Studio 致力于尋找 C、C++、C#、Java 在 Windows、Linux 和 macOS 上的 bugs。

另外本人是一名CC++的程序員,如果你想更好的提升你的編程能力,好好學(xué)習(xí)C/C++編程知識的話!那么你很幸運(yùn)~

分享(源碼、項(xiàng)目實(shí)戰(zhàn)視頻、項(xiàng)目筆記,基礎(chǔ)入門教程)

歡迎轉(zhuǎn)行和學(xué)習(xí)編程的伙伴,利用更多的資料學(xué)習(xí)成長比自己琢磨更快哦!

學(xué)習(xí)C/C++編程知識,提升C/C++編程能力,歡迎關(guān)注UP一起來成長!
另外,UP在主頁上傳了一些學(xué)習(xí)C/C++編程的視頻教程,有興趣或者正在學(xué)習(xí)的小伙伴一定要去看一看哦!會對你有幫助的~

編程學(xué)習(xí)書籍:


編程學(xué)習(xí)視頻:



程序人生:讀開源項(xiàng)目需謹(jǐn)慎!盤點(diǎn)C++開源項(xiàng)目中的十大BUG的評論 (共 條)

分享到微博請遵守國家法律
上蔡县| 河津市| 耿马| 南投县| 城口县| 玉山县| 临邑县| 社旗县| 邮箱| 安新县| 法库县| 阿拉善盟| 上犹县| 渭源县| 同仁县| 河间市| 土默特左旗| 遵化市| 巢湖市| 靖宇县| 合水县| 松溪县| 嘉兴市| 淅川县| 分宜县| 昭平县| 澳门| 司法| 高雄县| 兴安县| 宁蒗| 花莲市| 齐齐哈尔市| 尼勒克县| 广德县| 仪征市| 兴安县| 当雄县| 奉贤区| 兴城市| 武威市|