Александр Ильин писал(а):
Теперь важно понять вот что: значения DeltaR и SumNS правдоподобны или нет? Если нет, то сбой коренится где-то раньше, при их вычислении.
Нашёл, откуда берётся большое отрицательное значение DeltaR. В процедуре GeneralParticle.Move не всегда инициализируется поле r.PassedDistance.
Самым трудным было локализовать то место, в котором происходит исключение. Это нужно для того, чтобы выйти затем на переменную, принимающую некорректное значение, и найти "вверх по коду" то место, откуда это значение берётся. Трудность локализации в том, что оптимизированный код не содержит отладочной информации о границах процедур (например, многие заинлайнены). Глядишь на место сбоя в дизассемблере, и не понимаешь, какому месту в исходниках это соответствует, даже в каком модуле находишься.
Проблема была в неинициализированной стековой переменной (RECORD), поэтому сама ошибка носила "плавающий" характер в том смысле, что изменения в несвязанных местах кода могли приводить к изменению содержимого стека, и, соответственно, менять значение этой переменной на такое, которое не приводило к переполнению, и ошибка переставала проявляться. Это тоже затрудняло локализацию. Удалил строчку - ошибка пропала. Думаешь, ошибка в этой строчке? Подумай ещё раз. : )
Пришлось добавлять отладочную выдачу, чтобы видеть знакомый текст в дизассемблере, и понимать, где находишься.
Когда место сбоя локализовано в исходниках, остаётся понять, глючит ли кодогенератор, прочитывая не то значение, или в самом деле было не то передано в процедуру. Тут на помощь приходит отладочная выдача вида:
Код:
IF DeltaR < -6.E+0263 THEN (* here we get a value too small *)
Out.String('too small! ');
END;
Если оказывается, что и в самом деле такое некорректное значение было передано, то остаётся найти, откуда оно было получено. Опять же, это может быть сбой в вычислениях, ошибка кодогенерации или, как в данном случае, забытая инициализация.
Чтобы исправить ошибку, нужно в строке 165 модуля GeneralParticle заменить "PassedDistance:=0;" на "
r.PassedDistance:=0;".
GameHunter, c вас чай!