我有一個使用SQLite文件作爲文件格式的Windows窗體應用程序。這些文件由通過C++/CLI包裝器調用的本地代碼創建,其中包括對託管代碼的回調以進行更新/取消更新。這對於32位工作非常有效。我試圖通過切換到64位來消除我的內存限制,並且遇到了一個主要障礙。C#項目中的「優化代碼」選項如何導致本機代碼崩潰?
當內存在本地代碼內被分配或釋放時,我得到了僞確定性崩潰,這讓我想到了內存損壞。但它只發生在發佈版本中,只有在沒有附加調試器的情況下才會發生。這是我噩夢的細分:
Config Bits Optimizations Interop Dbg-symbols Runtime With-debugger Without-debugger Release 32 on no no /MD no crash no crash Release 64 on yes no /MD no crash no crash Release 32 on yes no /MD no crash no crash Release 64 on yes no /MD no crash crash Release 64 on yes yes /MD no crash crash Release 64 off yes no /MD no crash no crash Release 64 off yes yes /MD no crash no crash Debug 32 off no yes /MDd no crash no crash Debug 32 off yes yes /MDd no crash no crash Debug 64 off yes yes /MDd no crash no crash Debug 64 on yes yes /MD no crash no crash Debug 64 on yes no /MD no crash no crash Debug 64 off yes yes /MD no crash no crash Debug 64 off yes yes /MDd no crash no crash Debug 64 on yes yes /MDd no crash no crash Debug 64 on yes no /MD no crash no crash
「互操作」指的是我使用從GUI應用程序中的C++/CLI包裝來運行原有的語法分析器代碼。我有一個用本地C++編寫的命令行驅動程序,它不會在任何配置中崩潰。
基本上調試配置永遠不會崩潰,即使當本機代碼編譯完全像釋放代碼!我比較了響應文件,它們是相同的,除了我爲調試配置添加了_NO_DEBUG_HEAP = 1。無論如何,當我使用/ MD和定義NDEBUG時,我懷疑它有什麼影響。那麼,我該如何調試這個噩夢?它不覺得它是我的代碼的問題。請不要要求一個小的repro,我不知道如何做到這一點。但代碼全部是開源的,所以如果有人想重現這一點,我會發佈一個鏈接到源代碼。
添加'Trace :: WriteLine'來隔離到特定位置的崩潰。一旦你知道位置,你會找出原因。 –
@RomanR .:我怎麼可以在本機代碼中添加?我使用日誌記錄來將崩潰隔離到代碼的某些部分;這就是我知道這可能與分配或釋放內存有關。一個配置在清除矢量>時崩潰了,但實際上不應該釋放任何內存,它應該只是遞減所有ptrs的ref-count(它們全部都保存在別處)。我希望這很容易。 :( –
更新:我發現可以通過關閉C#項目中的「優化代碼」來避免崩潰(這就是爲什麼具有本機優化的調試配置可以正常工作的原因)。如何才能導致本機崩潰代碼?! –