It's with great hesitation that I pose this question because I know that whenever you think you've found a bug in something like the .NET framework it's probably just you doing something wrong. Never the less, I really can't figure out what has caused my current situation.
I'm building a ray tracer in C# and in a special case the return statement of a method is never called. The strange thing is that totally unrelated things affect when this behavior takes place.
You can see the offending method here:
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;
}
Only one thread is calling this method and on each call, the Console.Writeline statement is executed, but the return statement is never reached. The method is called hundreds of times and on each call, "was here" gets printed to the console.
If I comment out the second foreach (the one with all the comments in) the return statement is reached as normal, but the commented out code is never reached anyway. Other types of restructuring of the code can also make it run as intended but again not for any reason that makes sense to me.
This behavior looks more like some memory corruption issue one might encounter in C, so I haven't got any clues regarding what might have caused this - except a bug in .NET, that is.
Btw, the version of .NET I use is 3.5 sp1.
Update 3
In the end, it turned out that the break point had been eaten because I was in Release mode. I guess you learn something new every day.
Update 2
It seems I was so focused on the strange behavior that I didn't see the bug in my code. I have changed the code to reflect this but I'm still having the issue with never triggering the break point at the return statement - which points towards a bug in visual studio (2008) rather than .net. But my code now works, and I guess I'll have to settle with that.
Update
Here is the disassembly for stepping into the Console.Writeline function which is the last known location before the control flow disappears (There is no source code available to step into). I can't read assembly so I don't know what it means but it might make sense to someone out there.
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