![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Спасибо за ответы.
Я имел в виду, почему такое исключение заявлено (в книге), но не отлавливается, написанной от руки SEH-ловушкой с EXCEPTION_ARRAY_BOUNDS_EXCEEDED . А есть ли разница между CRT и C++ RTL? _RTC_Initialize - это инициализация CRT? (Например, Visual Fortran при компоновке своих приложений использует стартовые функции CRT и SEH-обработчик с _XcptFilter, но он же не должен пользоваться С++ RTL?) Рихтер пишет про _CppUnhandledExceptionHandler (для последней "обработки" стандартных С++ исключений до "глобального" для данного потока UnhandledExceptionHandler ). Однако в crt0.c или в crtexe.c есть _XcptFilter, а _CppUnhandledExceptionHandler нет, а в в crtdll.c. есть _CppUnhandledExceptionHandler но нет _XcptFilter. Как же реально это выглядит после компоновки приложения? Охватывает ли SEH c _CppUnhandledExceptionHandler SEH c _XcptFilter? Еще есть вопрос по функции _matherr , которая , будучи определенной пользователем в исходнике с программой, сама проявляет себя в некоторых критических ситауциях - как ей это удается, с помощью того же SEH или по-другому? (Связано ли это как-то с тем, что объявление _matherr содержится в crtexe.c ) |
|||
|
||||
| GremlinProg |
|
||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
проблема отлова такого исключения в том, что при затирании окружения массива может затереться сама запись SEH, она же находится так же, в стеке, просто чуть выше самого массива, поэтому будет довольно рисковано пытаться пройти по адресу этого обработчика это скорее всего инициализация счетчиков ошибок времени исполнения (RTC - Run-Time Error Checking): http://msdn.microsoft.com/en-us/library/w68b74dy.aspx CRT - изначально к С++ не относится ( C run-time library (without iostream or standard C++ library) ): http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx _CppUnhandledExceptionHandler - это я так понимаю встроенный обработчик от MSVC, для фортрана может быть свой обработчик: названия могут различаться, это же просто callback, который регистрируется через SetUnhandledExceptionFilter а какая разница? это же по сути - финальный фильтр исключений, если его не ставить, то будет работать встроенный UnhandledExceptionFilter, который уже покажет окно с ошибкой с возможностью дальнейшей отладки приложения встроенным отладчиком (правда это можно перекрыть, выставив SEM_NOGPFAULTERRORBOX).
ну тут вариантов не так много, конечно SEH, только она не будет работать, если маскировать контрольное слово FPU-исключений, но это в принципе и так понятно
да, отчасти:
т.е. пользовательский _matherr перекрывает встроенный, а встроенный, по-идее, должен просто возвращать 0, т.е. разрешить отображать окно с fpu-ошибкой, достаточно поставить в самом верху один SEH-фрейм на эти 6 исключений и всегда вызывать _matherr, независимо от того, пользовательская она или встроенная, т.е. без лишних наворотов с регистрацией обработчика реализуется FPU-сторож -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||||
|
|||||||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Я тут попробовал в одной программе, где просто просматривал статусное слово при FLT-операциях, менять контрольное слово (отключать FPU "обработку" тех или иных FLT-ошибок) и ловить и диагностировать их с помощью SEH.
Обнаружилась странная штука: если в ходе операции возникает одно исключение (например FLT_DIVIDE_BY_ZERO), то ловится все отлично, но если операция сопровождается 2-мя исключениями (например, при (упрощенный фрагмент)
возникает Overflow и Inexact), то ситуация странная, с одной стороны, до внешних обрабочиков (которые останавливают программу при остутствии моего SEH) дело не доходит, но и мой обработчик тоже реально не выполняется - программа прекращает выполнение в месте возникновения исключения. Я пробовал вложенные обработчики с фильтрами, настроенными непосредственно на вышеуказанные исключения - тоже не попадаю в тело обработчика и не получаю окошко от внешних (финальных) обработчиков (- программа прекращает выполнение в месте возникновения исключения.). Это сообщение отредактировал(а) FCM - 21.8.2009, 12:04 |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
этого кода я не понял, если ты хотел включить какое-то исключение, то во втором параметре нужно использовать не арифметические, а побитовые операции:
вот так я четко размаскировал только одно исключение, не затронув остальные, т.е. включил SEH только для _EM_OVERFLOW можешь проверить ps: _controlfp_s( &ctrl, 0, 0 ) вернет текущее слово управления FPU Это сообщение отредактировал(а) GremlinProg - 21.8.2009, 12:41 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
для включения сразу нескольких исключений все аналолгично:
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| FCM |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Там у меня опечатка (вследствие упрощения исходного текста)- должно быть int ctrl = _controlfp( _CW_DEFAULT - _EM_OVERFLOW- _EM_INEXACT , _MCW_EM); где _CW_DEFAULT согласно float.h равен сумме кодов fp-исключений и кое-чего еще
Поэтому записи вида _CW_DEFAULT-_EM_OVERFLOW или _CW_DEFAULT-_EM_OVERFLOW - _EM_INEXACT в функции _controlfp в принципе корректны (им наплевать на текущее контрольное слово они берут максимальную маску и отнимают код(ы) исключения, которое FPU должен сгенерить), хотя менее професcиональны чем побитовый вариант. В любом случае я просматриваю контрольное слово в двоичном формате и вижу, что сработало. Вопрос был немного в другом. в ходе операции float r = d; возникает два исключения OVERFLOW и INEXACT (я их виже просматривая статусное слово) и мой пользовательский SEH-обработчик не может сам полноценно ухватить это "двойное" исключение, и кроме того мешает внешним SEН обработчикам (от OC) вывести соотв. окошко (с кодом зафиксированного исключения). ( Или это фокусы компилятора MSVC7?). |
||||
|
|||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
покажи содержимое регистра SR, т.к. я вупор не вижу двух одновременных исключений со всеми твоими параметрами, статус XX88 задает поднятые: третий и седьмой биты регистра SR, которые говорят только о переполнении (INEXACT - это пятый бит, нумерация бит - с нуля) -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Как просмотреть регистр я не знаю.
Я вывожу текущее контрольное слово до моих установок имею в двоичном формате 1001 0000 0000 0001 1111 после моих установок с изменением маски для Overflow и Inexact 1001 0000 0000 0001 1010 где 1000 0000 0000 0000 0000 - denormal 1 0000 - invalid 1000 - zerodivide 100 - overflow 10 - underflow 1 - inexact |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
контрольное слово вообще ни чего не говорит о произошедших исключениях,
ты в этом слове только маскируешь прерывания, которые должны произойти реально, произощедшие исключения можно посмотреть в первых восьми битах слова статуса - SR под отладчиком просто открой вкладку "регистры" и добавь к ним FPU в MSVC соответствие регистров такое: CR - это CTRL SR - это STAT вот в STAT и смотри -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Забыл написать, что я и статусное слово тоже просматриваю (с помощью __statusfp) и вижу при вышеуказанных действиях:
101 (левые нулевые биты не отображаю) В отладчике тоже посмотрю. |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
1) Кажется я понял в чем дело.
Я запускал в Debug-сборке через Ctrl+F5 (запуск без отладки) и получал то, что получал. Если я запускаю в Debug через F5, то попадаю в свои ловушки, а поскольку в них только вывожу информацию, то в итоге получаю в окошечке внизу : First_chance exception и далее описание и код исключения. В Releas'e попадаю в свои ловушки, как и должно быть. Интересно, в чем фишка с Ctrl+F5 (запуск без отладки) - какие-то "подводные камни"? 2) Если открыть окошко Debug/Exceptions, то видим 4 или 5 (в МVС9) групп исключений. Последняя Win32 как я понимаю - аппаратные; одна(в МVС7) или две (в МVС9) группы только для управляемого кода; одна группа для CRT ловушек. А что значит группа для С++ исключений?: _com_error _ATL::CAtlException CExeption std::exception void Это сообщение отредактировал(а) FCM - 22.8.2009, 09:40 |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
вот сейчас получил 2 ошибки одновременно, но эти 2 ошибки выставляются в статусе только если отключены исключения, стоит только включить SEH на обе, и статус начинает говорить нам только об одной ошибке - переполнение, т.е. ни каких программных проблем тут нет, просто видимо команда перестает выполняться при обнаружении первого немаскированного исключения
включи в CR только _EM_INEXACT и получишь оба флага поднятых ( _EM_OVERFLOW и _EM_INEXACT ) но бросается конечно же только одно исключение, для которого оно разрешено суть видимо в том, что первое действие fstp - это все же загрузка регистра, а уже второе - проверка его содержимого на точность Добавлено через 8 минут и 57 секунд ну так, естественно, Ctrl+F5 независимо от сборки, не подключает отладчик к процессу вообще последние - это как раз SEH исключения то же самое, что и все остальные - это окно позволяет приостанавливать отладчик, если генерируется какое-то из этих исключений, на Release-сборку это не оказывает ни какого влияния (просто в дебаге удобно по-быстрому найти ошибку, не расставляя брейкпойнты) -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
не оказывает ни какого влияния вообще на любую сборку, запущенного вне отладчика -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Понятно, спасибо
А вот применение signal - это только для установки дополнительных "пунктов" для _XcptFilter? Или что-то более универсальное? |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
в winxfltr.c описана реализация _XcptFilter и __CppXcptFilter
а в crtdll.c, dllcrt0.c, crtexe.c, crt0.c - их использование разница между ними только в том, что __CppXcptFilter перехватывает только одно искусственное исключение 'msc'|0xE0000000, которое определяет С++ исключение с передачей в нем экземпляра класса (по сути - это враппер над _XcptFilter) а _XcptFilter обрабатывает сразу серию исключений из _XcptActTab:
вот по этой таблице и определяется, какой сигнал соответствует Win32-исключению signal и raise - видимо, приближение к юниксам, влияние signal может распространяться как на _XcptFilter, так и за его пределами (как например в abort) в пределах _XcptFilter, signal позволяет разделить и переопределить его встроенное поведение а все, что пропускает _XcptFilter идет уже на финальную обработку, стоящую где-то на уровне создания процесса, т.е., скорее всего, где-то в недрах загрузчика можно сказать, signal - универсальный обработчик исключений, правда только их небольшого набора и не всегда именно через SEH -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |