我目前正在一個相當大(和老,嘆)代碼庫,最近升級到VS2005(SP1)。我和我的團隊正在改變/更新/替換此代碼中的模塊,但我們偶爾會遇到vtables似乎破裂的問題。我不是vtables的專家,但這些確定似乎已被打破。錯誤表現與此錯誤:VS2005 C++破vtables
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
當然可以有很多其他原因造成的錯誤,但調試(調試版本)時,其實我可以確認爲對象的虛函數表我想上一下運行奇怪:
引用每個vtable的堆棧和堆看起來很好,並且指向vtable的指針與映射文件完全匹配。這表明這不是內存覆蓋錯誤或類似的問題,因爲那樣會影響堆棧和堆,而不是存儲vtables的位置。 (它們被存儲在只讀區域中嗎?)無論如何,目前所有這些看起來都不錯。但是當查看vtable的內存時,我發現所有的值,如果我將它們解釋爲指針,儘管它們在相同的範圍內(例如,0x00f203db 0x00f0f9be 0x00ecdda7 0x00f171e1)與映射文件中的任何條目都不匹配,並且其中很多甚至沒有對齊到4個字節。我不知道VS2005如何構建vtables的所有細節,但這看起來不對。如果這是正確的行爲,也許有人可以向我解釋這一點?
我想我的問題歸結爲什麼會導致這種行爲?例如,當太複雜的類層次結構時,鏈接器中是否有任何已知的錯誤?有沒有人見過類似的東西?目前,我們可以通過將受影響的類的函數移至內聯(可怕的東西!)來解決我們的崩潰問題,但顯然這不是一個可行的長期解決方案。
感謝您的任何見解!
更新:我被問到關於該項目的更多細節,當然我會提供這個。但首先,問題並不完全與ESP值不被保存錯誤相關。我最感興趣的是爲什麼我在vtable中看到奇怪的值。這就是說,這裏有一些額外的信息:解決方案依賴於幾個外部和內部項目,但這些都沒有改變很長一段時間,所有使用相同的調用約定。它似乎打破的代碼都在解決方案的一個非常標準的C++「主」項目中。所有代碼都使用相同的編譯器構建。該解決方案還沒有使用任何DLL,但是用大量靜態庫的鏈接:
SHFolder.lib,python25.lib,DXGUID.LIB,d3d9.lib,d3dx9.lib,dinput8.lib,ddraw.lib,dxerr9 .lib ws2_32.lib mss32.lib Winmm.lib vtuneapi.lib vttriggers.lib DbgHelp.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ,shell32.lib,ole32.lib,oleaut32.lib,uuid.lib,odbc32.lib,odbccp32.lib
嗨,謝謝!上面的問題增加了一些更多的信息。 – Dan 2009-02-24 09:32:04
bwah ...我很難過,因爲你的構建環境看起來很健全。讓我考慮一下這個問題,並回來一些新的建議/問題。 – 2009-02-24 14:06:38
呵呵,是的,我在這裏也畫了一個空白,除了我看到的奇怪的vtable。感謝您提出任何想法:) – Dan 2009-02-25 03:52:13