Самоанализ с плавающей точкой в ​​VS2010 - как проверить без взлома?

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

Проблема в том, что наш код должен вызывать код клиента как dll. Мы контролируем наш код, а не клиентов, и опыт показывает, что их код не всегда безупречен. Я защитил от ошибок сегментации, выйдя из программы с четким сообщением о том, что могло бы пойти не так, но у меня также было несколько исключений деления на ноль, исходящих из кода клиента, который я хотел бы идентифицировать и затем выйдите.

То, что я хотел сделать, это:

  1. Непосредственно перед запуском dll клиентов, включив самоанализ с плавающей точкой.
  2. Запустите клиентский код.
  3. Проверьте на любые проблемы.
  4. Выключите самоанализ для скорости.

Теоретически существует несколько способов сделать это, но многие не работают на 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. Документация правильная или предупреждение (я держу пари на предупреждении)?
  2. Есть ли надежный и безопасный способ сделать это?
  3. Должен ли я делать это вообще, или это слишком опасно?

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 не может изменить уже скомпилированный код.

Итак, ответы:

  1. Оба верны
  2. Да, _controlfp_s
  3. Вам не хватает статуса SSE2, поэтому он по крайней мере неполный
Другие вопросы по тегам