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

jopen 10年前發布 | 8K 次閱讀 C/C++開發 C/C++

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

錯誤代碼

BOOL WINAPI DllMain( HINSTANCE hinstDLL,
                     DWORD fdwReason, LPVOID lpvReserved )
{
  ....
  CreateThread( NULL, 0, ParentMonitorThreadProc,
                (LPVOID)dwParentProcessId, 0, &dwThreadId );
  ....
}

解釋:

很久以前,我曾經在

業余

時間接過一些項目。有一次我就接了一個項目,但是最后沒有搞定。這個項目本身就有問題,但是當時我并不知道。更麻煩的是,這個項目乍一看還蠻簡單的。

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

我花了大量時間做這個項目,但是代碼就是不工作。更糟糕的是,如果我 創 建一個標準的新應用, 這段代碼 就沒問題,一旦我把 代碼 放到 DllMain 里去運行就不行。簡直是個謎,不是嗎?我最后還是 沒有找出問題的根源 。

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

我們現在有了診斷工具,可以提醒程序員在 DllMain 里直接用哪些操作是危險的。現在我終于明白那時程序不能運行的原因了。

關于不能在 DllMain 里執行哪些操作的更多細節 ,可以查看(PVS-Studio)關于 V718 診斷信息的描述。

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

正確的代碼:

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

建議:

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

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

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

來自: http://blog.jobbole.com/97070/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!