vs debug 模式生成的exe 另一台电脑_神秘的 _DEBUG 宏从何处来?
緣起
在上一篇文章 《調試實戰 —— dll 加載失敗之Debug Release爭鋒篇》中,由于兩個工程中的 _ITERATOR_DEBUG_LEVEL 不同,導致了對同一個 map 的解析不同,從而導致了崩潰。在示例代碼中,我是手動更改的該宏的值,在實際工程中,卻另有玄機。在上文中故意省略了這部分內容的介紹。現把實際工程的問題在本文中做個相對詳細的梳理總結。
先劇透一下:實際工程中的問題是因為一個工程中定義了 _DEBUG 宏,另外一個工程里沒定義。但是我已經核對過,兩個工程都沒定義 _DEBUG 宏。其中一個工程的 _DEBUG 宏是從哪兒來的呢?
測試工程簡介
為了查出 _DEBUG 宏從何而來,我特意建了一個超級簡單的工程。只包含一個源文件,其內容如下:
#ifdef _DEBUG #pragma message("---- _DEBUG defined.") #else #pragma message("---- _DEBUG NOT defined.") #endifint wmain() {return 0; }相信大家都知道,debug 會定義 _DEBUG 宏,而 release 不會定義 _DEBUG 宏。默認的 debug 和 release 中對應的 Preprocessor definition 配置對比如下圖:
最開始,我以為簡單的刪掉 _DEBUG 宏,編譯的時候就不會有 _DEBUG 宏了。
沒想到……
頑強的 _DEBUG 宏
再次編譯的時候, _DEBUG 宏還是被定義了。
誤入歧途
根據經驗,工程配置可以直接存儲在工程文件(后綴一般是 .vcxproj),也可以存儲在 .props 文件中。在 TestDebugMacro.vcxproj 中搜索 _DEBUG 宏,一無所獲!會不會存儲在 .props 中呢?使用 File Locator 搜索關鍵字 _DEBUG,搜索條件如下圖:
只搜到了幾條相關的記錄,因為使用的是 vs2013,對應的版本號是 v120,所以只需要關注高亮的搜索記錄。
雖然,看上去不太可能,但是抱著試試看的心態,刪除 Microsoft.Cpp.AppContainerApplication.props 第 104 行的 _DEBUG 宏,
重新編譯。結果, _DEBUG 宏,依然頑強的活著。這里就不截圖了。
會不會記錄在注冊表里呢?搜索一番,一無所獲!
肯定是記錄到哪里了,應該不會動態生成吧?!
繼續搜索
擴大搜索范圍,在所有文件中搜索,經過排查,只有 cl.exe 中的記錄比較靠譜。
難道寫死在 cl.exe 中了?有點兒不可思議。(文中暗表,確實寫死在 cl.exe 中了。)
順著這條路已經找不到更多有價值的線索了,需要換個思路了。
換個思路
會不會是 vs 在編譯的時候,根據某些條件自動添加的?為了排除這種情況,直接使用 msbuild.exe 進行構建操作(在 《全局變量初始化順序探究》里已經介紹過了)。
可以發現,直接使用 msbuild.exe 編譯也會定義 _DEBUG 宏。可以把 vs 從懷疑名單中劃掉了。
注意看傳遞給 cl.exe 的參數(上圖黃色高亮部分)中也沒有 _DEBUG 宏的蹤影。
難道是 msbuild 通過進程通信手段實現的?(真佩服自己的腦洞)
試試直接使用 cl.exe TestDebugMacro.cpp 編譯。
柳暗花明
居然 _DEBUG 宏消失了!!!
通過 msbuild.exe 啟動的 cl.exe ,從日志可以發現 cl.exe 的參數如下:
C:Program Files (x86)Microsoft Visual Studio 12.0VCbinCL.exe /c /ZI /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _CONSOLE /D _LIB/D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Debug" /Fd"Debugvc120.pdb" /Gd /TP/analyze- /errorReport:queue TestDebugMacro.cpp而手動執行的 cl.exe 只傳遞了需要編譯的文件名。會不會是哪個神奇的參數搞的鬼呢?好辦,二分法排查!
經過幾次嘗試,很快定位到是 /MDd 搞得鬼!
/MDd 選項是何方神圣?搜索一下,很快找到了微軟官方的介紹。
/MDd 選項
官方文檔很明確的描述到:/MDd 選項會定義 _DEBUG,_MT 和 _DLL ,并且會使用調試 版本的多線程運行時庫。
具體請介紹參考微軟官方文檔截圖:
貼一張工程屬性設置截圖。
反思
當時沒有嚴格按照對比的思路進行排查,浪費了很多時間!
很久之前確實對比過 /MDd 幾種選項的不同,當時的關注點主要在于會鏈接不同的運行時庫,忽略了對宏的影響。相信經過這次折騰,我永遠也忘不了 /MDd 選項定義 _DEBUG 宏。這個行為不是通過配置文件發生的,而是寫到了 cl.exe 的文件中!
總結
- File Locator 真可謂文件內容搜索神器,經常排錯的小伙伴兒必備!
- 一種情況是正常,一種情況不正常,最簡單粗暴有效的辦法就是對比!
- 排查問題時,我們要盡量簡化問題,盡可能排除無關條件的干擾。
- /MDd 選項不僅會影響鏈接庫,還會定義 _DEBUG 宏。
參考資料
https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=vs-2019
總結
以上是生活随笔為你收集整理的vs debug 模式生成的exe 另一台电脑_神秘的 _DEBUG 宏从何处来?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 类组合_python类与对
- 下一篇: 为什么python不出结果_Python