2010-11-05 109 views
7

背景: 我正在使用DirectX 9.0托管库将3d点的数组转换为2D屏幕坐标。对于速度,我使用UnsafeNativeMethods进行所有转换。为什么此代码抛出System.ExecutionEngineException

问题: 如果使用我的自定义线裁剪功能,我的应用程序死了,没有抛出任何异常,我花了一段时间才能弄清楚,它抛出一个抓不到System.ExecutionEngineException。由于剪辑功能的最后两行,我缩小了范围。

List<Vector3> verticesAfterClipping = new List<Vector3>; 
public unsafe void ClipLine(Line lineToClip) 
{ 
    this.verticesAfterClipping.Clear(); 

    // Clipping algorithm happens here... (this is psuedo-code of what it does) 
    foreach(Vertex in lineToClip.Vertices) 
    { 
     bool thisIsClipped = // Set to whether this vertex is clipped 
     bool lastWasClipped = // Set to whether last vertex was clipped 

     if(thisIsClipped == false && lastWasClipped == true) 
     { 
      verticesAfterClipping.Add(/* intersection on clipping plane */); 
      verticesAfterClipping.Add(/* thisVertex */); 
     } 
     else if (thisIsClipped == false && lastWasClipped == false) 
     { 
      verticesAfterClipping.Add(/* thisVertex */); 
     } 
     else if (thisIsClipped == true && lastWasClipped == false) 
     { 
      verticesAfterClipping.Add(/* intersection on clipping plane */); 
     } 
    } 

    // THIS IS WHERE BAD THINGS HAPPEN 
    lineToClip.Vertices = new Vertex[verticesAfterClipping.Count]; 
    verticesAfterClipping.CopyTo(lineToClip.Vertices, 0); 
} 

verticesAfterClipping列表复制到lineToClip顶点则lineToClip对象被传递给一个UnsafeNativeMethod其将这些顶点到2d中的顶点。当我以调试模式浏览它时,我能看到的所有东西都能正常工作,直到它死亡。

我根本无法弄清楚什么是错的。任何帮助将非常感激。

回答

12

该问题实际上可能不会在引发异常的行中发生。这可能只是早些时候发生的事情的一个症状。

当CLR 检测到某些事情已经发生了可怕的错误时,将引发System.ExecutionEngineException异常。问题发生后,这可能会发生相当长的时间。这是因为异常通常是内部数据结构被破坏的结果 - CLR发现某些事情进入了一种毫无意义的状态。它会抛出一个不可捕捉的异常,因为它不安全。

因此,您可能会在某些完全不相关的系统中破坏某些东西的代码,但只有在运行这段代码时才会变得明显。你显示的代码可能会很好。 (它也可能不是......我没有看到任何明显的错误,但是我不知道DX 9托管库的好处,例如,我看不到这个方法的哪个特征需要不安全的关键字。 )

不幸的是,这意味着你需要开始投网更广泛。几乎任何使用不安全代码的东西,或COM互操作都有可能被怀疑。可悲的是,这将是一个漫长而乏味的过程。你可能会采取的一种方法是逐渐简化程序:能够说明问题的最小代码是什么? (例如,如果你把你在那里显示的代码放到一个应用程序中,除了对该方法的最简单的调用,它是否仍然失败?)

+0

当你说在这两行中不发生异常时,你是对的,但它确实发生在这两行的结果中。 我替换了这些行,并使用另一个临时缓冲区来复制剪辑的顶点,现在一切正常。我认为当这行被传递给不安全的本地directx方法时,会发生某种内存访问冲突。 – tbridge 2010-11-08 00:10:37

+3

不要认为没有ExecutionEngineException意味着问题已消失。它可能仅仅是CLR不再检测到它。通过替换这些行,您现在可能处于数据被破坏的情况,但您不再有异常。 (CLR没有也不能保证在任何时候抛出ExecutionEngineException这样的错误,只有当它发生时才会抛出它。)所以我会担心的 - 我一定会试图到达底部*如何发生这次事故,就像现在一样,没有理由确信你已经修复了它。 – 2010-11-08 14:29:28

1

我对于不同的库有同样的问题。在我的情况下,所有人都开始很久以前,因为我必须在64位环境中运行32位.net应用程序。那么这会给我带来很多麻烦,体系结构之间的兼容性问题,或者.NET框架的CLR问题也可能是您的问题。

PS:现在我知道什么我的麻烦是,但不知道其中是它。

相关问题