C++/CLI:当 debugging/stepping 进入 32 位代码时发生访问冲突 (VS-2015)

C++/CLI: Access violation when debugging/stepping into code in 32-bit (VS-2015)

我在调试 32 位混合模式程序集时单步执行代码时遇到了这个奇怪的问题。代码的精简版本如下所示:

public ref class FooClass {
    public:
        FooClass();
};

FooClass::FooClass(){
    // Note: doesn't matter what code is in here, as long as it is native
    char test[10];
    memset((void*)test, 0, sizeof(test));
}

这个class然后在另一个class中实例化:

FooClass^ BarClass::Test() {
    FooClass^ addr = gcnew FooClass();
    return addr;
}

..再次在 C# 控制台应用程序中实例化:

class Program
{
    static void Main(string[] args)
    {
        BarClass bar = new BarClass();
        FooClass foo  = bar.Test();
    }
}

单步执行代码并进入 FooClass 构造函数时,出现异常

(注意:为了减少混乱,删除了参数信息):

ntdll.dll!_NtTraceEvent@16()    Unknown
ntdll.dll!EtwpEventWriteFull()  Unknown
ntdll.dll!_EtwEventWrite@20()   Unknown
clrjit.dll!Compiler::lvaInitTypeRef() Line 253  C++
clrjit.dll!Compiler::compCompileHelper(...) Line 3489   C++
clrjit.dll!Compiler::compCompile(...) Line 3092 C++
clrjit.dll!jitNativeCode(...) Line 4063 C++
clrjit.dll!CILJit::compileMethod(...) Line 180  C++
[Managed to Native Transition]  
>   FooBar.dll!FooBar::BarClass::Test() Line 16 C++
ConsoleApp.exe!ConsoleApp.Program.Main(string[] args) Line 15   C#

但是,如果我只是在构造函数中添加断点并且只是 运行 下一个断点,代码运行正常。

此外,当删除本机代码时,它运行良好。

64 位模式下不会出现此问题。我交叉检查了设置,但看不出有什么特别之处。

没有第 3 方 dll,所有本机代码都编译到程序集中。

这不是我的第一个 C++/CLI 项目,但是我第一次在 VS2015 中做。

根据我原来问题的评论,建议如下:

  1. 进入工具 -> 选项 -> 调试 -> 常规
  2. 启用 "Use Managed Compatibility Mode" 复选框

这解决了问题。

在我的例子中,问题是内部托管组件中的异常,它显然没有很好地传播到调用它的本机层 - 并且表现为这个不可能的 ETW 堆栈。

为了调试,我必须附加为仅托管。异常正对着我(缺少 DLL,但这无关紧要)。

希望这对那里的人有所帮助。