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