Самоанализ с плавающей точкой в VS2010 - как проверить без взлома?
Я как бы ходил по домам и думал, что нашел решение. Это, безусловно, правильно определяет проблемы, о которых я знаю, но также приводит к необъяснимым сбоям примерно в половине всех тестов системы.
Проблема в том, что наш код должен вызывать код клиента как dll. Мы контролируем наш код, а не клиентов, и опыт показывает, что их код не всегда безупречен. Я защитил от ошибок сегментации, выйдя из программы с четким сообщением о том, что могло бы пойти не так, но у меня также было несколько исключений деления на ноль, исходящих из кода клиента, который я хотел бы идентифицировать и затем выйдите.
То, что я хотел сделать, это:
- Непосредственно перед запуском dll клиентов, включив самоанализ с плавающей точкой.
- Запустите клиентский код.
- Проверьте на любые проблемы.
- Выключите самоанализ для скорости.
Теоретически существует несколько способов сделать это, но многие не работают на VS2010.
Я пытался использовать прагму с плавающей точкой:
#pragma float_control(except, on, push)
// run client code
#pragma float_control(pop)
__asm fwait; // This forces the floating point unit to synchronise
if (_statusfp() & _SW_ZERODIVIDE)
{
// abort the program
}
Это должно быть хорошо в теории, и на практике это работает хорошо в 50% случаев.
Я думаю, что проблема может быть в том, что элемент управления с плавающей точкой остается включенным и вызывает проблемы в других частях кода.
По данным microsoft.com:
"/ Fp: точный, /fp: быстрый, /fp: строгий и / fp: кроме переключателей управляют семантикой с плавающей запятой для каждого файла отдельно. Прагма float_control обеспечивает такой контроль для каждой функции в отдельности ".
Однако во время компиляции я получаю предупреждение:
предупреждение C4177: #pragma 'float_control' следует использовать только в глобальной области видимости или области имен
Что на первый взгляд является прямым противоречием.
Итак, мой вопрос:
- Документация правильная или предупреждение (я держу пари на предупреждении)?
- Есть ли надежный и безопасный способ сделать это?
- Должен ли я делать это вообще, или это слишком опасно?
1 ответ
Ты пытался
#pragma float_control(except, on, push)
// run client code
#pragma float_control(pop)
Это не так, как это работает. Это директива компилятора, и это означает,
#pragma float_control(except, on, push)
// This entire function is compiled with float_control exceptions on.
// Therefore, the pragma has to appear outside the function, at global scope.
#pragma float_control(pop)
И, конечно, этот параметр влияет только на компилируемую функцию (-и), никакие функции, которые они могут вызывать, такие как ваши клиенты. #Pragma не может изменить уже скомпилированный код.
Итак, ответы:
- Оба верны
- Да,
_controlfp_s
- Вам не хватает статуса SSE2, поэтому он по крайней мере неполный