故障排除错误代码 1000 应用程序崩溃

troubleshooting error code 1000 application crash

问题已解决警报。首先阅读最终更新。 ...................................................

我有一个通过 COM 调用 c# 库的 vb6 应用程序

C# 库是 Framework 4.5.2

如果我在特定机器上构建 COM 库 运行 VS2017 15.5.6 我没有问题。

如果我在特定记录中使用 vS2017 15.5.2 签出相同的代码并在不同的机器上构建它(我尝试了其中的 2 个),我会遇到应用程序崩溃。

错误发生在代码行

if (edge.Extra == null) // 给定边不为空且 Extra 是 属性

在Windows事件日志中有

Faulting application name: jtJobTalk.exe, version: 1.0.0.0, time stamp: 0x5a9f5b1c
Faulting module name: ntdll.dll, version: 6.3.9600.18895, time stamp: 0x5a4b127e
Exception code: 0xc00000fd
Fault offset: 0x0006d46c
Faulting process ID: 0xb74
Faulting application start time: 0x01d3b5c77355520d
Faulting application path: C:\jobtalk\jtJobTalk.exe
Faulting module path: C:\Windows\SYSTEM32\ntdll.dll
Report ID: d1374fd2-21ba-11e8-8272-d050999dc03c

我尝试了 sfc 扫描,没有报告任何问题。

在另一台计算机上 (运行 Windows 7) 我收到错误

A new guard page for the stack cannot be created

如何进一步解决此问题?

怕更新好机器上的VS版本,万一导致我无法发布

[更新]

在对 MessageBox.Show 进行了一些调用后,我确定该错误是由一个对象从它自己的构造函数中引用自身引起的。

我至少花了一天时间才弄明白。我正在寻找任何可以帮助我更轻松地诊断问题的智慧之珠。

Exception code: 0xc00000fd

即STATUS_STACK_OVERFLOW。一个非常常见的事故,而且很难调试,以至于他们以它命名了一个流行的程序员网站。在调试器的帮助很少的情况下,您将获得此事故的原始版本。始终是互操作代码中的一个问题,您不能依赖托管调试器引擎来帮助您诊断它。 Google 是您的最佳选择,此短语的所有热门点击可帮助您走上正确的道路,开始修复它。

If I build the COM library on a particular machine...

那就是运气不好,翻错石头找原因,一时糊涂。 SOE 永远不会由构建问题或错误的 VS 版本引起,始终是编码错误。它会发生在一台机器上而不是另一台机器上的最基本原因是您没有使用完全相同的数据测试程序。或者快速更改代码,看起来很无辜,但事实并非如此。

if (edge.Extra == null)

这是 SOE 的一个非常常见的原因,一个有问题的 属性 getter。像这样:

public class Example {
    private Foo edge;
    public Foo Edge {
        get { return Edge; }   // Oops, meant edge
    }
}

你当然可以看一会,再也看不到了。如果编译器有一个诊断程序就好了,但是 C# 编译器没有必要的管道来查出这个。另一个非常常见的原因是字段初始值设定项:

public class Example {
    private Example foo = new Example();
    // etc...
}

从那里很容易变得更加复杂,例如,当您创建另一个 class 的实例时,class 在其构造函数中创建一个 Example 对象。而C#语言支持编写递归代码,是标准的编程技术之一。如果该代码比 O(log(n)) 更复杂,那么您总是可以很容易地用太多数据使它崩溃。

...any pearls of wisdom

是的,有一个。如果您没有托管调试引擎来帮助处理异常,那么诊断错误将变得非常困难。 VB6 运行时可以为您提供异常消息,但不能提供 Holy Stack Trace。在两个截然不同的运行时环境之间转换时丢失的信息。

但是你可以吃蛋糕也可以吃,诀窍是让托管调试器启动 VB6 IDE。 Right-click 你的 C# class 库项目 > 属性 > 调试选项卡。 Select "Start external program" 单选按钮并键入 "C:\Program Files (x86)\Microsoft Visual Studio\VB6\VB6.exe"。您可以选择将 "Command line arguments" 设置为您的 .vbp 项目的完整路径,这样 IDE 会自动加载您的 VB6 项目。使用 Debug > Windows > Exception Settings 并勾选 "Common Language Runtime Exceptions" 复选框,以便它显示刻度线。这会使调试器在任何 C# 异常被传递到您的 VB6 代码之前停止。

按 F5,VB6 IDE 启动 运行。再次按 F5 以启动 VB6 代码。 C# 代码中的任何错误现在都会导致托管调试器介入。通常显示会自动切换到 VS IDE,但有时您必须单击闪烁的任务栏按钮。您可以查看引发异常的代码并使用 Debug > Windows > Stack Trace 来了解它是如何到达那里的。

我不是 100% 确定这也适用于诊断 SOE,VB6 运行时可能介入得太早以致 CLR 无法看到异常。我没有再安装 VB6 来检查。请尝试并告诉我。