日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

vs debug 模式生成的exe 另一台电脑_神秘的 _DEBUG 宏从何处来?

發(fā)布時間:2025/3/21 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vs debug 模式生成的exe 另一台电脑_神秘的 _DEBUG 宏从何处来? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

緣起

在上一篇文章 《調(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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。