Ошибка в .NET? - PullRequest
       52

Ошибка в .NET?

2 голосов
/ 12 мая 2009

Я с большим колебанием задаю этот вопрос, потому что я знаю, что всякий раз, когда вы думаете, что нашли ошибку в чем-то вроде .NET Framework, скорее всего, вы просто делаете что-то не так. Тем не менее, я действительно не могу понять, что вызвало мою текущую ситуацию.

Я создаю трассировщик лучей в 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, но оператор возврата никогда не достигается. Метод вызывается сотни раз, и при каждом вызове «был здесь» выводится на консоль.

Если я закомментирую второй foreach (тот, в котором все комментарии), оператор return будет выполнен как обычно, но закомментированный код никогда не будет достигнут. Другие типы реструктуризации кода также могут заставить его работать как задумано, но опять же не по любой причине, которая имеет для меня смысл.

Это поведение больше похоже на проблему повреждения памяти, с которой можно столкнуться в 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

Ответы [ 3 ]

2 голосов
/ 13 мая 2009

Мораль этой истории такова: если вы спросите «Является ли это ошибкой в ​​{.NET, C #, Windows}», то ответ, вероятно, «Нет». Миллионы и миллионы людей используют эти вещи, поэтому вероятность того, что you окажется тем, кто найдет ошибку, довольно мала - даже если бы была ошибка, кто-то другой найдет ее первой.

Исключением может быть случай, когда вы один из немногих людей в мире, которые могли испытать ошибку. Это повышает вероятность того, что вы его нашли. Это может быть связано с тем, что вы используете бета-версию, или потому, что вы работаете в каком-то неясном уголке программного обеспечения.

Но многие люди видели бы ошибку с "оператором возврата никогда не выполнялся". Поскольку вы вряд ли будете первым, кто увидит эту ошибку, вы вряд ли столкнетесь с ошибкой вообще.

Спасибо человеку, который сказал мне, что я на самом деле не обнаружил ошибку в операционной системе TOPS-10 несколько лет назад

1 голос
/ 13 мая 2009

Откуда вы знаете, что подпрограмма не вызывает исключение? Попробуйте обернуть все в попытку / поймать.

0 голосов
/ 13 мая 2009

Что происходит в вызывающем методе после выполнения трассировки?

Если ответ, как я ожидаю, «ничего», это почти наверняка проблема с многопоточностью. Либо ваш поток каждый раз блокируется в одной и той же точке (маловероятно), либо метод, из которого вы вызываете, кооптируется или блокируется между добавлением метода в стек и извлечением возвращаемого значения из него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...