Нужно предусмотреть любое развитие событий в каждой функции, при этом диагностику выводить информативно. Приложение мультипоточно. Какой вариант посоветуете?
Реализовать в виде макроса было бы удобно. Что-то вроде
FX_TRY
... // тут кончается память, место на диске, шнур из розетки вылетает итд.
FX_CATCH
Log( /* тут выводить подробную инфу, откуда? */ )
FX_FINALLY
... // освобождаем ресурсы
По собственному опыту, как бы эти макросы реализовать лучше?
Здравствуйте, zaufi, Вы писали:
Z>Здравствуйте, licedey, Вы писали:
L>>По собственному опыту, как бы эти макросы реализовать лучше?
Z>по собственному опыту лучше с макросами не связываться насколько это возможно. а в данном случае это вполне возможно:
Z>
Z>void handle_exceptions()
Z>{
Z>#if defined(__GNUC__) && GCC_VERSION > 40100
Z> assert("No need to call this function w/o active exception" && 0 != abi::__cxa_current_exception_type());
Z>#endif
Z> try
Z> {
Z> throw;
Z> }
Z> catch (const std::runtime_error& e) {
Z> // handle it!
Z> }
Z> //
Z> // ... catch any other concrete exception types here...
Z> //
Z> catch (const std::exception& e) {
Z> // handle it!
Z> }
Z>}
Z>void some_function()
Z>{
Z> try
Z> {
Z> // do smth what may throw exceptions...
Z> }
Z> catch (...)
Z> {
Z> handle_exceptions();
Z> }
Z>}
Z>void another_function()
Z>{
Z> try
Z> {
Z> // do some other stuff what may throw exceptions...
Z> }
Z> catch (...)
Z> {
Z> handle_exceptions();
Z> }
Z>}
Z>
Насколько я понял из кода, handle_exceptions — хватает все возможное? В том числе например, деление на 0, обращение к NULL или к уже освобожденной памяти? Можете ткнуть где все возможные exception'ы перечислены, под MSVS в частности. И WinApi обработка исключений, тоже интересует. Заранее благодарен.
Здравствуйте, licedey, Вы писали:
L>Насколько я понял из кода, handle_exceptions — хватает все возможное? В том числе например, деление на 0, обращение к NULL или к уже освобожденной памяти? Можете ткнуть где все возможные exception'ы перечислены, под MSVS в частности. И WinApi обработка исключений, тоже интересует. Заранее благодарен.
А предполагается ли смешивать обработку C++ных и структурных исключений?
Можно попробовать транслировать SEH в C++ (хотя бы на уровень catch(...), как исключение неопознанного типа — компилятор такое умеет) и в обработчике смотреть, не SEH ли это, и если да, то какой именно.
А можно сразу __try-__except.
И смотреть на код исключения (GetExceptionCode).
Здравствуйте, licedey, Вы писали:
l> Нужно предусмотреть любое развитие событий в каждой функции, при этом диагностику выводить информативно. Приложение мультипоточно. Какой вариант посоветуете? l> Реализовать в виде макроса было бы удобно. Что-то вроде
l> FX_TRY l> ... // тут кончается память, место на диске, шнур из розетки вылетает итд. l> FX_CATCH l> Log( /* тут выводить подробную инфу, откуда? */ ) l> FX_FINALLY l> ... // освобождаем ресурсы
l> По собственному опыту, как бы эти макросы реализовать лучше?
мне кажется, что вы немного неверно сформулировали задачу.
Написать приложение, которое корректно работает с исключениями -- это достаточно сложная задача, требующая тщательного планирования и большого опыта. Почитать об этом можно у таких грандов как Саттер, Александреску и др.
К тому же вы планируете использовать аппаратные исключения кидаемые из ядра Windows.
Тернистая дорожка получается...
Может попробовать зайти с другой стороны: спроектировать и написать приложение таким образом, чтобы всевозможные отказы не были исключительной ситуацией, а были заранее предусмотрены?
Тогда никаких особенных требований не будет ни к обработке исключений, ни к логированию.
Здравствуйте, avbochagov, Вы писали:
A>Здравствуйте, licedey, Вы писали:
l>> Нужно предусмотреть любое развитие событий в каждой функции, при этом диагностику выводить информативно. Приложение мультипоточно. Какой вариант посоветуете? l>> Реализовать в виде макроса было бы удобно. Что-то вроде
l>> FX_TRY l>> ... // тут кончается память, место на диске, шнур из розетки вылетает итд. l>> FX_CATCH l>> Log( /* тут выводить подробную инфу, откуда? */ ) l>> FX_FINALLY l>> ... // освобождаем ресурсы
l>> По собственному опыту, как бы эти макросы реализовать лучше?
A>мне кажется, что вы немного неверно сформулировали задачу.
A>Написать приложение, которое корректно работает с исключениями -- это достаточно сложная задача, требующая тщательного планирования и большого опыта. Почитать об этом можно у таких грандов как Саттер, Александреску и др. A>К тому же вы планируете использовать аппаратные исключения кидаемые из ядра Windows. A>Тернистая дорожка получается...
A>Может попробовать зайти с другой стороны: спроектировать и написать приложение таким образом, чтобы всевозможные отказы не были исключительной ситуацией, а были заранее предусмотрены? A>Тогда никаких особенных требований не будет ни к обработке исключений, ни к логированию.
Я уточню. Мой проект — это антивирусный сканер, DLL с несколькими функциями, к которым могут обращаться несколько разных consumer'ов (процессов, других DLL). Каждая функция запускает свой поток с задачей. Например ScanFolder или ScanCookies. Все пишется на MS C++/WinAPI/STL. Моя задача, чтобы при любых раскладах consumer не завис при "падении" одной задачи. Проверять коды возврата WinApi и диагностировать GetLastError() я так понимаю будет достаточно. Но есть еще С++ исключения.
Как посоветуете быть. Наиболее простым будет, обернуть проверка коды возврата WinApi-функций и генерировать свой WinApiException например. Тела топовых-функций облачить в try/catch и как в ответе Кодт'a, обрабатывать стандартные С++ exceptions+WinApiException. Что посоветуете? Вариант с "Предусмотреть все" не получится, хотя бы потому что вызывающий код мне неизвестен.
Еще вопрос. Можно ли перехватывать технические исключения в MSVS C++? Допущенные по невнимательности. Как, переполнение стека, обращение за пределы адресного пространства? Часто бывает вылет — memory access on adresss 0xxx corrupted.
Здравствуйте, licedey, Вы писали:
L>Еще вопрос. Можно ли перехватывать технические исключения в MSVS C++? Допущенные по невнимательности. Как, переполнение стека, обращение за пределы адресного пространства? Часто бывает вылет — memory access on adresss 0xxx corrupted.
Баги в программе нужно фиксить, а не заметать под ковёр.
Здравствуйте, licedey, Вы писали:
l> Я уточню. Мой проект — это антивирусный сканер, DLL с несколькими функциями, к которым могут обращаться несколько разных consumer'ов (процессов, других DLL). Каждая функция запускает свой поток с задачей. Например ScanFolder или ScanCookies. Все пишется на MS C++/WinAPI/STL. Моя задача, чтобы при любых раскладах consumer не завис при "падении" одной задачи. Проверять коды возврата WinApi и диагностировать GetLastError() я так понимаю будет достаточно. Но есть еще С++ исключения.
Правильно ли я понял: Вы пишете DLL, которую дергают другие приложения за "выставленные" наружу функции. Так?
С++ исключения — это свойства языка. Получить исключение можно только если его кто-то явным образом создал с помощью throw.
l> Как посоветуете быть. Наиболее простым будет, обернуть проверка коды возврата WinApi-функций и генерировать свой WinApiException например. Тела топовых-функций облачить в try/catch и как в ответе Кодт'a, обрабатывать стандартные С++ exceptions+WinApiException. Что посоветуете?
Если я правильно понял как должна работать ваша DLL, то я посоветую ровно тоже самое что и Кодт. Только маленькое уточнение -- ваша DLL должна состоять из двух слоёв: Внешний интерфейс DLL — пишется на чистом С. Никаких исключений тут нет. Только коды возврата. Основная его задача провести все возможные проврки и передать аргументы (если они правильные) в следующий слой. Почему чистый С: это позволит использовать вашу библиотеку с минимальными усилиями на всем спектре языков программирования для Windows.
А здесь уже Ваша основная логика, написанная на C++. Если хотите использовать исключения — то они никогда не должны отсюда уходить в первый слой.
l> Вариант с "Предусмотреть все" не получится, хотя бы потому что вызывающий код мне неизвестен.
А Вам и не надо "Предусмотреть все". Достаточно, чтобы Ваш код принимал только правильные параметры и корректно по ним отрабатывал. В случае некорретных параметров, или возникновения ошибки достаточно вернуть код ошибки, возможно с расширенным описанием для улучшения диагностики.
l> Еще вопрос. Можно ли перехватывать технические исключения в MSVS C++? Допущенные по невнимательности. Как, переполнение стека, обращение за пределы адресного пространства? Часто бывает вылет — memory access on adresss 0xxx corrupted.
А вот этого быть не должно никогда.
Такие ошибки должны быть пойманы на этапе тестирования.
У вас ведь есть план тестирования?
l> Спасибо.
P.S. что касается технических исключений, то достаточно подумать, что вы сможете сделать если разрушен стэк? и из этого строить политику по их использованию.