簡體   English   中英

Windows C++ MFC 遷移:AfxGetThread 斷言。 為什么在某些情況下 win32u.dll 在 mfc140d.dll 之前加載?

[英]Windows C++ MFC migration: AfxGetThread Assertion. Why does win32u.dll load before mfc140d.dll in some cases?

我有為 Visual Studio 6.0 MFC 編寫的客戶代碼,它有一個簡單的 GUI,並啟動一個帶有 arguments 的 EXE。這段代碼大約在 2 年前從 VS6.0 移植到 VS2019,並在多個系統的生產環境中工作。 我們現在有一個新系統,其中的代碼無法顯示為 function... 我開始挖掘。

代碼在 appcore.cpp 第 196 行拋出異常它在 AfxGetThread() 崩潰,現在我已經能夠讓 VS2019 找到“appcore.cpp”。
在此處輸入圖像描述

這是新信息。接下來我將在 AfxGetThread 上搜索......所以這個問題現在可能是重復的。

我檢測到的一個差異是 Visual Studio 2019 調試器加載符號的順序。 我不能肯定地說這是運行時實際 DLL 加載順序的指示,但它似乎是。 下面的屏幕截圖是 SYMBOL 加載順序,其中檢測到應用程序的工作實例和非工作實例之間存在差異。

在下圖中,我們有兩個 ASCII 文件的 Tortoise SVN Diff。 一種是應用程序工作時左側的DLL符號加載順序。 第二個是應用程序運行失敗時右側的DLL符號加載順序。 第 7 行是差異,在失敗的情況下,庫 win32u.dll 在 mfc140d.dll 之前被拉入。

在此處輸入圖像描述

客戶代碼使用了一些我需要調查的 Apache log4cxx 庫,但此時在加載序列中,我不能 100% 確定這些庫或構建時使用的 *.h 文件的差異會影響 DLL 加載順序。

所以這就是我正在看的謎題。

我將包含一些指向相關 StackOverflow 問題的鏈接,這些問題與我搜索此問題的答案時類似。

可能有用的鏈接: https://learn.microsoft.com/en-us/cpp/porting/porting-guide-mfc-scribble?view=msvc-170

DLL 在不同位置按順序搜索: Standard Search Order for Desktop Applications

故障機器上的 DLL 很可能丟失或位於錯誤的位置,因此 Windows 會獲取其他內容。

確保所有依賴項都安裝在正確的文件夾中。

在這種情況下,appcore.cpp 的崩潰是由於代碼中有 2 個 CWinApp 派生對象。 崩潰發生在施工期間。

第一個障礙是讓 VisualStudio2019找到appcore.cpp 並能夠單步執行此代碼。 我瀏覽到C:\Program Files(x86)\VisualStudio並搜索“appcore.cpp”。 這提供了面包屑的蹤跡,以便在 Visual Studio2019 請求文件時獲得正確的路徑。

在我的例子中,路徑是:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30037\atlmfc\src\appcore.cpp

在此處輸入圖像描述

第二個障礙是在 ASSERT 點下一個斷點,因為程序第一次出現時,這個 ASSERT 是可以的。 至少在我的情況下...... CWinApp object 的第一個構造函數成功了。 所以在我的例子中,攻擊性代碼意外地構建了一個 CWinApp 派生的 object 首先運行。 然后將通過 ASSERT 進行第二次迭代。

通過在 ASSERT 處放置一個斷點,您可以重新啟動並查看成功的 object 的堆棧跟蹤以確定它是否符合預期。

在此處輸入圖像描述

在我的例子中,需要一個 *.h 修復程序才能使古老的 Visual Studio 6.0 MFC 代碼成功構建和鏈接。 我沒有確切的秘密,但它實際上是在包含 afx.h 之前獲取 *.h 以指定正確的 WIN_VER 最小 windows 版本。 對於失敗的代碼,包含了一個不正確的 *.h,其中包含派生 CWinApp 的修復 PLUS 對象。

據我所知,這在某些站點上起作用而在其他站點上不起作用的原因是由於在該特定系統上構建的代碼出現了回歸。

另一個“奇怪”的行為是在帶有錯誤*.h 的系統上包含 DLL 符號加載順序不同。 我能夠在多個運行“錯誤”Exe 代碼的系統上復制這種不良行為。 然后我對工作的 *.exe 代碼做了同樣的事情。 奇怪的是,“壞”的 exe 在工作區中有相當正確的來源。 因此,存在源代碼控制問題,導致人們認為它在一個節點上工作,而不在其他節點上工作。 我能夠捕捉到與提交給源代碼管理的過時代碼相匹配的運行時行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM