我非常犹豫地提出了这个问题,因为我知道无论何时你认为你在.NET框架中发现了一个错误,你可能只是在做错事。从来没有,我真的无法弄清楚是什么导致了我目前的情况。
我正在使用C#构建光线跟踪器,在特殊情况下,永远不会调用方法的return语句。奇怪的是,完全不相关的事情会影响这种行为。
您可以在此处查看违规方法:
public Primitive FindNearest(ref float distance, Ray ray, ref RayCollision collisionResult)
{
if (!_initialized) InitUnit();
Primitive hitPrimitive = null;
//Search the planes
foreach (var plane in RenderEngine.Scene.Planes)
{
RayCollision collision = plane.Intersect(ray, ref distance);
if (collision != RayCollision.Miss)
{
hitPrimitive = plane;
collisionResult = collision;
}
}
if (_spatialStructure == null)
{
//Default collision detection
foreach (Primitive primitive in _primitives)
{
//RayCollision collision = primitive.Intersect(ray, ref distance);
//if (collision != RayCollision.Miss)
//{
// hitPrimitive = primitive;
// collisionResult = collision;
//}
}
}
else
{
//hitPrimitive = _spatialStructure.GetClosestIntersectionPrimitive(ray, ref distance, out collisionResult);
//Console.WriteLine("Was here");
RayCollision collision;
Primitive prim = _spatialStructure.GetClosestIntersectionPrimitive(ray, ref distance, out collision);
if (collision != RayCollision.Miss)
{
hitPrimitive = prim;
collisionResult = collision;
}
}
return hitPrimitive;
}
只有一个线程正在调用此方法,并且在每次调用时,都会执行Console.Writeline语句,但永远不会到达return语句。该方法被调用数百次,并且在每次调用时,“在这里”被打印到控制台。
如果我注释掉第二个foreach(带有所有注释的那个),则返回语句正常,但是注释掉的代码无论如何都不会到达。其他类型的代码重组也可以使其按预期运行,但同样不会出于任何对我有意义的原因。
这种行为看起来更像是在C中可能遇到的一些内存损坏问题,所以我没有任何关于可能导致这种情况的线索 - 除了.NET中的错误,即。
顺便说一句,我使用的.NET版本是3.5 sp1。
更新3
最后,事实证明断点已被吃掉,因为我处于发布模式。我猜你每天都学到新东西。
更新2
我似乎专注于奇怪的行为,我没有看到我的代码中的错误。我已经改变了代码以反映这一点,但我仍然遇到问题,从不在return语句中触发断点 - 这指向visual studio(2008)中的错误,而不是.net。但我的代码现在有效,我想我必须解决这个问题。
更新
这是用于步入Console.Writeline函数的反汇编,它是控制流消失之前的最后一个已知位置(没有可用的源代码可供使用)。我不能阅读汇编,所以我不知道这意味着什么,但它可能对那里的人有意义。
0000002a mov r11,qword ptr [rbx+20h]
0000002e mov rax,qword ptr [r11]
00000031 mov rdx,rdi
00000034 mov rcx,r11
00000037 call qword ptr [rax+000001A0h]
0000003d lea rdx,[rbp+8]
00000041 mov rcx,rbx
00000044 call FFFFFFFFFFF0C410
00000049 jmp 0000000000000050
0000004b jmp 0000000000000050
0000004d nop dword ptr [rax]
00000050 lea rsp,[rbp+10h]
00000054 pop rdi
00000055 pop rbp
00000056 pop rbx
00000057 rep ret
00000059 push rbx
0000005a push rbp
0000005b push rdi
0000005c sub rsp,30h
00000060 mov rbp,qword ptr [rcx+20h]
00000064 mov qword ptr [rsp+20h],rbp
00000069 lea rbp,[rbp+20h]
0000006d lea rdx,[rbp+8]
00000071 mov rcx,qword ptr [rbp+30h]
00000075 call FFFFFFFFFF56F3E9
0000007a nop
0000007b add rsp,30h
0000007f pop rdi
00000080 pop rbp
00000081 pop rbx
00000082 rep ret
答案 0 :(得分:2)
故事的寓意是,如果你问“这是{.NET,C#,Windows}中的错误”,那么答案可能是“不”。数以百万计的人使用这些东西,因此你找到错误的机会非常小 - 即使有错误,其他人也会先找到它。
例外情况是,您是世界上为数不多的可能遇到过该错误的人之一。这使你更有可能找到它。这可能是因为您正在使用测试版,或者因为您正在使用该软件的一些模糊角落。
但很多人会看到“返回语句从未执行过”的错误。由于您不太可能是第一个看到此错误的人,因此您根本不可能遇到错误。
感谢那位告诉我事实上,几年前TOPS-10操作系统中没有发现错误的人
答案 1 :(得分:1)
你怎么知道子程序没有抛出异常?尝试将它们全部包装在try / catch中。
答案 2 :(得分:0)
Trace执行后调用方法会发生什么?
如果答案是,正如我所料,“没有”,这几乎肯定是一个线程问题。您的线程每次都被锁定在同一点(不太可能),或者在将方法添加到堆栈并从中检索返回值之前,您正在调用的方法正在被选择或阻止。