Обнаружены странные баги. Может быть кто-то их полечил?
Есть 2 модуля: DLL и EXE. DLL скомпилено с /EHa, EXE — с /EHs. DLL ставит свою функцию трансляции каких-то SE исключений в С++ исключение CMyException. EXE отлавливает CMyException.
SE происходит в недрах DLL. Отрабатывает функция трансляции, кидается CMyException. Если теперь CMyException не поймано в DLL, а летит за пределы модуля в вызывающий EXE, то вместо того чтобы быть обработаным в EXE оно валит приложение. Точнее приложение падает с оригинальным SE исключением.
Если откомпилить EXE с /EHa, то все работает. Исключение штатно ловится внутри EXE.
Если в DLL поймать CMyException и сделать "throw;", то все падает.
Если в DLL поймать CMyException и создать новый CMyException и кинуть его взамен, то все работает.
И не ясно почему C++ исключение может валить приложение..
Цель — не требовать вызывающий модуль быть /EHa. Получается что это достигается только перехватом C++ исключения во всех экспортируемых DLL функциях. При этом исключение нужно поймать и пересоздать и кинуть заново.. Бред.
Другой вариант решения __try / __except вместо _set_se_translator. Но этот вариант еще хуже, т.к. самодельные __try блоки запрещают иметь в функции объекты с деструкторами и нужно все передавать через ссылки или указатели.
Re[2]: _set_se_translator преодаление границ модуля
E>Цель — не требовать вызывающий модуль быть /EHa. Получается что это достигается только перехватом C++ исключения во всех экспортируемых DLL функциях. При этом исключение нужно поймать и пересоздать и кинуть заново.. Бред.
Зачем вообще DLL собирать с /EHa ?
плюсовые исключения кидаются через throw
Если же нарвались на невалидный указатель, то надо писать креш-дамп и завершаться.
Re[2]: _set_se_translator преодаление границ модуля
Здравствуйте, eks314, Вы писали:
E>Цель — не требовать вызывающий модуль быть /EHa. Получается что это достигается только перехватом C++ исключения во всех экспортируемых DLL функциях. При этом исключение нужно поймать и пересоздать и кинуть заново.. Бред.
Кидать С++-ные исключения за пределы модуля почти всегда плохая идея. Это иногда может быть нормально, если разделение на модули чисто логическое, то есть приложение остается единым. Но в таком случае непонятно почему бы не привести параметры компиляции к общему знаменателю. Если приложение концептуально не едино, например модули могут поставляться другими разработчиками, то такой подход в корне неверен, потому как привязывает этих других разработчиков к точно той же версии рантайма, что и во всех остальных модулях.
Re[3]: _set_se_translator преодаление границ модуля
От:
Аноним
Дата:
15.06.09 15:36
Оценка:
Здравствуйте, K13, Вы писали:
K13>Зачем вообще DLL собирать с /EHa ? K13>плюсовые исключения кидаются через throw K13>Если же нарвались на невалидный указатель, то надо писать креш-дамп и завершаться.
MSDN статья "Reading and Writing From a File View"
...
Reading from or writing to a file view of a file other than the page file can cause an EXCEPTION_IN_PAGE_ERROR exception. For example, accessing a mapped file that resides on a remote server can generate an exception if the connection to the server is lost.
...
Это пример случая, когда нужно обрабатывать SEH.
Re[3]: _set_se_translator преодаление границ модуля
От:
Аноним
Дата:
15.06.09 15:54
Оценка:
Здравствуйте, Sergey Chadov, Вы писали:
SC>Кидать С++-ные исключения за пределы модуля почти всегда плохая идея. Это иногда может быть нормально, если разделение на модули чисто логическое, то есть приложение остается единым. Но в таком случае непонятно почему бы не привести параметры компиляции к общему знаменателю. Если приложение концептуально не едино, например модули могут поставляться другими разработчиками, то такой подход в корне неверен, потому как привязывает этих других разработчиков к точно той же версии рантайма, что и во всех остальных модулях.
Наша DLL используется несколькими нашими приложениями. И runtime будет един. В принципе, конечно, мы можем попросить всех пользователей использовать EHa. Но, во-первых, не понятно почему мы должны так делать, ведь механизм _set_se_translator ничего такого в общем не требует (исходя из описания).
У нас есть оговоренный механзм связи наших DLL (общая библиотека). Наша DLL начинает выбиваться из общих правил и ставит доп. требование на вызывающее приложение. Также существует DLL, которая использует проблемную DLL в своих целях. Получается что и ей нужно требовать EHa от пользователя. Лишние связи, о которых хочется избавиться. + вроде бы есть какая-то потеря производительности при использовании EHa вместо EHs, но здесь не очень разбираюсь, может быть несущественно.