每天學點C++知識:用合適的工具來分析你的程式碼

黃小非發表於2016-01-14

靜態程式碼分析工具可簡化編碼過程,檢測出錯誤並幫助修復。有個國外團隊檢測了 200 多個 C/C++ 開源專案,包括了 Php、Qt 和 Linux 核心等知名專案。於是他們每天分享一個錯誤案例,並給出相應建議。伯樂線上翻譯組正在翻譯這個系列。今天的案例來自 LibreOffice 專案。


錯誤程式碼

解釋:

很久以前,我曾經在業餘時間接過一些專案。有一次我就接了一個專案,但是最後沒有搞定。這個專案本身就有問題,但是當時我並不知道。更麻煩的是,這個專案乍一看還蠻簡單的。

其實就是在 DllMain 方法中,當某些條件觸發時,用 Windows API 函式實現一些功能。我記不太清楚要實現哪些功能了,但是肯定不難。

我花了大量時間做這個專案,但是程式碼就是不工作。更糟糕的是,如果我建一個標準的新應用,這段程式碼就沒問題,一旦我把程式碼放到 DllMain 裡去執行就不行。簡直是個謎,不是嗎?我最後還是沒有找出問題的根源

多年以後的今天,我使用 PVS-Studio 開發工具後,我突然意識到當年問題的原因。你,其實 DllMain 函式能正確執行的操作非常有限,因為(很多操作依賴的)DLL 庫並沒有被載入,所以你不能直接在 DllMain 裡就直接執行任意的操作。

我們現在有了診斷工具,可以提醒程式設計師在 DllMain 裡直接用哪些操作是危險的。現在我終於明白那時程式不能執行的原因了。

關於不能在 DllMain 裡執行哪些操作的更多細節,可以檢視(PVS-Studio)關於 V718 診斷資訊的描述。

所以,上面那段 LibreOffice 的程式碼片段很可能就無法工作。它能不能正常執行完全要靠運氣。

正確的程式碼:

要修復這類錯誤其實很難。你需要重構整個程式碼邏輯,讓 DllMain 函式裡的操作越簡潔越好。

建議:

對於這類問題並沒有什麼特別的建議。你不可能什麼都知道,每個人總有一天都會遇到類似的謎題。我認為一個比較普遍的建議是這樣的:請仔細地閱讀和工作相關的各種文件。但你還是要明白,人們無法預測每一個可能出現的問題。如果你把所有的時間都拿去閱讀文件了,那又怎麼有時間去程式設計呢?即使你已經讀了很多頁的文件,你也不確認有沒有漏看了某個文件,而它是可以讓你免於犯錯的

我希望能給更加實用的建議(來避免這些難以捕捉的錯誤),但是很遺憾我只能想到一條:使用靜態分析工具。當然這還是不能保證你就不會犯錯了。但是至少這麼做會讓你犯錯的機率降低。如果當年我有了這些工具,那我就絕對不會在 DllMain 裡去呼叫我寫的那些程式碼,那麼我很可能就能節省大量時間,少死好多腦細胞。要知道,我對當時沒能搞定那個任務一直耿耿於懷!

這個錯誤由 PVS-Studio 靜態分析工具捕獲。錯誤文字:V718:“CreateThread”方法不應該在“DllMain”方法中呼叫。

打賞支援我翻譯更多好文章,謝謝!

打賞譯者

打賞支援我翻譯更多好文章,謝謝!

每天學點C++知識:用合適的工具來分析你的程式碼

相關文章