Введение - длинная и скучная часть
(вопрос в конце)
У меня сильная головная боль из-за стороннего компонента COM, который постоянно меняет управляющее слово FPU.
Моя среда разработки - Windows и Visual C ++ 2008. Обычное управляющее слово FPU указывает, что исключение не должно создаваться при различных условиях. Я проверил это как при просмотре макроса _CW_DEFAULT
, найденного в float.h
, так и при просмотре контрольного слова в отладчике при запуске.
Каждый раз, когда я обращаюсь к COM-объекту, управляющее слово изменяется при возврате. Это легко защитить от. Я просто сбрасываю контрольное слово, и все хорошо. Проблема в том, что компонент COM начинает вызывать мой приемник событий. Я могу защитить свой код, сбрасывая управляющее слово, как только получаю вызов события, но я ничего не могу сделать, как только я возвращаюсь из вызова события.
У меня нет источника для этого COM-компонента, но я общаюсь с автором. Ответы, которые я получил от него, были «А?». Я не думаю, что он имеет хоть малейшее представление о том, о чем я говорю, поэтому я боюсь, что должен сам что-то с этим сделать. Я считаю, что его среда выполнения (я думаю, это либо Delphi, либо Borland C ++, потому что DLL полна имен символов, все начинаются с заглавной буквы T), либо какой-то другой сторонний код, который он использует, вызывает проблему. Я не думаю, что его код явно изменяет управляющее слово FPU.
Итак, что я могу сделать? С точки зрения бизнеса крайне важно использовать этот сторонний компонент. С технической точки зрения я мог бы отказаться от него и сам реализовать протокол связи. Однако это будет очень дорого, так как этот протокол включает обработку транзакций по кредитным картам. Мы не хотим брать на себя ответственность.
Мне крайне необходим хакерский обход или некоторая полезная информация о настройках FPU в продуктах Borland, которую я могу передать автору компонента.
Вопросы
Есть ли что-нибудь, что я могу сделать? Я не думаю, что автор компонента имеет то, что нужно, чтобы исправить это (судя по его довольно невежественным ответам).
Я играю с идеей установить свой собственный обработчик исключений, в котором я просто сбрасываю управляющее слово в обработчике и приказываю Windows продолжить выполнение. Я попытался установить обработчик с SetUnhandledExceptionFilter()
, но по какой-то причине исключения не перехватываются.
- Почему я не ловлю исключения?
- Если мне удастся перехватить исключения FPU, сбросить управляющее слово FPU и просто позволить продолжить выполнение, так как ничего не произошло - все ли тогда ставки?
Обновление
Я хотел бы поблагодарить всех за их предложения. Я отправил автору инструкции о том, что он может сделать, чтобы облегчить жизнь не только мне, но и многим другим клиентам его кода. Я предложил ему, чтобы он взял контрольное слово FPU на DllMain(DLL_PROCESS_ATTACH)
и сохранил контрольное слово на потом, чтобы он мог сбросить FPU CW перед вызовом моих обработчиков событий и возвращением из моих вызовов.
Пока что у меня есть хакерство, если кому-то интересно. Взлом является потенциально плохим, потому что я не знаю, что он сделает с его кодом. Ранее я получил подтверждение, что он не использует числа с плавающей запятой в своем коде, так что это должно быть безопасно, за исключением некоторого стороннего кода, который он использует, который полагается на исключения FPU.
Две модификации, которые я внес в свое приложение:
- Обернуть мой насос сообщений
- Установите крюк окна (
WH_CALLWNDPROC
), чтобы поймать угловые случаи, когда насос сообщений обойден
В обоих случаях я проверяю, изменился ли FPU CW. Если это так, я сбрасываю его на _CW_DEFAULT
.