“怎么可能?”;“优化代码”;C#项目中的选项是否会导致本机代码崩溃?

“怎么可能?”;“优化代码”;C#项目中的选项是否会导致本机代码崩溃?,c#,visual-studio-2010,debugging,c++-cli,C#,Visual Studio 2010,Debugging,C++ Cli,我有一个Windows窗体应用程序,它使用SQLite文件作为文件格式。这些文件由本机代码创建,本机代码通过C++/CLI包装器调用,其中包括对托管代码的回调以进行进度/取消更新。这在32位系统中一直非常有效。我试图通过切换到64位来消除我的内存上限,但遇到了一个重大障碍 当在本机代码中分配或释放内存时,会出现伪确定性崩溃,这让我想到内存损坏。但它只在发布版本期间发生,并且只在没有附加调试程序的情况下发生。下面是我噩梦的分解图: Config Bits Optimizations Inter

我有一个Windows窗体应用程序,它使用SQLite文件作为文件格式。这些文件由本机代码创建,本机代码通过C++/CLI包装器调用,其中包括对托管代码的回调以进行进度/取消更新。这在32位系统中一直非常有效。我试图通过切换到64位来消除我的内存上限,但遇到了一个重大障碍

当在本机代码中分配或释放内存时,会出现伪确定性崩溃,这让我想到内存损坏。但它只在发布版本期间发生,并且只在没有附加调试程序的情况下发生。下面是我噩梦的分解图:

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 配置位优化与不带调试器的调试器运行时互操作Dbg符号 第32版无故障/MD无故障无故障 发布64是否/MD否崩溃否崩溃 发布32关于是否/MD否碰撞否碰撞 发布64是否/MD否崩溃 是是/MD否崩溃时发布64 发布64关是否/MD否碰撞否碰撞 发布64关是是/MD否碰撞否碰撞 调试32关闭否是/MDd否崩溃否崩溃 调试32关是是/MDd否崩溃否崩溃 调试64关闭是是/MDd否崩溃否崩溃 调试64是是/MD否崩溃否崩溃 调试64是否/MD否崩溃否崩溃 调试64关闭是是/MD否崩溃否崩溃 调试64关闭是是/MDd否崩溃否崩溃 调试64是是/MDd否崩溃否崩溃 调试64是否/MD否崩溃否崩溃 “Interop”意味着我正在使用GUI应用程序中的C++/CLI包装器来运行本机解析器代码。我有一个命令行驱动程序,它是用C++编写的,在任何配置中都不会崩溃。
基本上,调试配置从不崩溃,即使本机代码的编译与发行版代码完全相同!我比较了响应文件,它们是相同的,只是我为调试配置添加了_NO_DEBUG_HEAP=1。我怀疑这在使用/MD和定义NDEBUG时会有任何影响。那么我如何调试这个噩梦呢?我觉得我的代码没有问题。请不要要求小小的修改,我不知道怎么做。但是代码都是开源的,所以如果有人想复制它,我会发布一个到源代码的链接。

Heisenbug通常是由内存阻塞(在托管代码中不会发生)或将内存中的垃圾视为有效数据引起的

我已经找到了多个通常可重复的海森堡,最终使用了一个未初始化的变量,该变量将从另一个例程中提取堆栈上的任何内容。您的本机代码可能包含这样一个bug,当它得到一个值时,它会工作,当它得到另一个值时,它会崩溃。Debug vs release不能保证幕后的东西是相同的(毕竟,如果是这样,为什么会有这两种配置?),而且内存中可能有不同的垃圾

优化器也可能有这样的效果

我想尝试的一件事是:在本机代码的第一个例程的局部变量中插入一个实质性的结构。对它做些什么以防止链接器剥离它


这将使事情四处移动,如果是内存中的垃圾问题,这将改变行为。

添加
Trace::WriteLine
将崩溃隔离到特定位置。一旦你知道了位置,你就会找出原因。@RomanR:我怎么能把它添加到本机代码中呢?我使用日志记录将崩溃隔离到代码的某些部分;这就是我知道它可能与分配或释放内存有关的原因。一个配置在清除向量时崩溃,但实际上不应该释放任何内存,它应该只是减少所有PTR的引用计数(它们都保存在其他位置)。我希望能这么容易(更新:我发现可以通过关闭C#项目中的“优化代码”来避免崩溃(这就是为什么带有本机优化的调试配置可以正常工作的原因)。这怎么会导致本机代码崩溃?!这听起来像是本机端未初始化的堆栈变量。当禁用优化时,.NET端初始化的堆栈部分可能与启用时不同。此外,请检查是否需要。为什么调试程序不会捕获本机代码中的此类错误ap在我的非互操作案例中?@MattChambers:另一个版本可能会在内存中留下可接受的内容。