
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.75] |
![]() |
|
Страницы: (6) 1 [2] 3 4 ... Последняя » все ( Перейти к последнему сообщению ) |
![]() |
Сообщ.
#16
,
|
|
Сообщ.
#17
,
|
|
|
Цитата Qraizer @ Чего? Я там редактировал, пока ты там читал! =) Перечитай есчо раз =) |
![]() |
Сообщ.
#18
,
|
|
Я правильно прочитал. Ты предлагаешь мне схавать аппаратное исключение? Это оффтоп темы
|
Сообщ.
#19
,
|
|
|
Цитата Qraizer @ Я правильно прочитал. Ты предлагаешь мне схавать аппаратное исключение? Это оффтоп темы А ты что, в сказку попал?!! 1) Есть сетевые ошибки, масса 2) Есть ошибки устройств I/O, часто 3) Крайний случай - тупо ошибки RAM, нечасто но видели Я тебе предлагаю это схавать! =) |
![]() |
Сообщ.
#20
,
|
|
Majestio, не рекомендую троллить или подменять термины. Можешь, конечно, подумать на предмет
![]() ![]() LONG WINAPI translateException(EXCEPTION_POINTERS *excPtr) { const unsigned EH_EXCEPTION_NUMBER = ('msc' | 0xE0000000); // <- undocumented if (excPtr->ExceptionRecord->ExceptionCode == EH_EXCEPTION_NUMBER) return EXCEPTION_CONTINUE_SEARCH; throw StackTrace(excPtr->ExceptionRecord->ExceptionCode); // dangerously } // нуль int b = 0; int g() { return 123 / b; // деление на нуль } int f() { return g(); } int main() { HANDLE hExc = AddVectoredExceptionHandler(1, translateException); if (hExc == NULL) return std::cout << "AddVectoredExceptionHandler() fails: " << GetLastError() << std::endl, 1; Guard excRem([=](){ RemoveVectoredExceptionHandler(hExc); }); try { f(); } catch(const StackTrace& exc) { std::clog << std::hex << exc.why() << "\nStack trace -->:\n" << exc.getStack(); return 2; } return 0; } Цитата Majestio @ ни к теме C++EH 1) Есть сетевые ошибки, масса 2) Есть ошибки устройств I/O, часто 3) Крайний случай - тупо ошибки RAM, нечасто но видели |
Сообщ.
#21
,
|
|
|
Цитата Qraizer @ Majestio, не рекомендую троллить или подменять термины. И в помыслах не было! Просто я немножко на позитиве в следствие принятия соответствующих, скажем так, пищевых добавок ![]() Цитата Qraizer @ Ты предлагаешь мне схавать аппаратное исключение? Желаю уточнить. Мы сейчас говорим о юзер-спэйсе. И все что может быть "выкинуто" аппаратурой - мы не ловим напрямую, а ждем реакции исключительно операционной системы. Работу проги в режиме ядра операционной системы, или тем паче, вообще без операционной системы - мы щяс не рассматриваем. Поэтому да - сетевые ошибки, и ошибки I/O могут уверенно прилетать в юзерспейс, уже тёплые, ламповые, готовые. И там (в юзерспейсе) они могут и должны обрабатываться. Что касается аппаратных ошибок RAM - тут согласен. Эту "беду" на прикладном уровне очень сложно, а чаще и невозможно, победить. Цитата Qraizer @ WINAPI А вот тут ты очень обидно сказал!!! ![]() И кстати тут: Цитата Qraizer @ int g() { return 123 / b; // деление на нуль } В рамках программирования "здорового человека" нужно немного поправить сигнатуру функции. А именно проверять b на нуль. И принимать одно из решений, учитывая тему топика: 1) Выкидывать свое исключение, оставив сигнатуру функции как есть 2) Либо поступить как поступают в других ЯП типа Rust/Dart - возвращать не int, а Result. Который, для упрощения, есть структура с полями "валидное_значение?" и "значение". Ну если не структура, пусть будет std::tuple. Не важно, главное принцип - "видишь деление, проверь". Тоже самое касается и остальных мест, где могут быть проблемсы. |
![]() |
Сообщ.
#22
,
|
|
Ты всё-таки определись, что ты хочешь. О ловле контекста, приводящему к аппаратному отказу, с целью его недопущения я уже писал:
![]() ![]() std::optional<int> g() { return b == 0 ? decltype(g())() : 123 / b; // деление на нуль } int f() { return g().value(); } ![]() ![]() std::variant<int, std::error_code> g() { using retType = decltype(g()); return b == 0 ? retType(std::make_error_code(std::errc::invalid_argument)) : retType(123 / b); // деление на нуль } int f() { return std::get<int>(g()); } Если же мы говорим от аппаратных отказах, то Стандартного способа преобразовать исключения низкого уровня в C++EH не существует и вряд ли когда-нибудь будет существовать. В WINAPI испокон веков существовал SEH (даже в Win16, хоть и в очень зачаточном виде). Это часть API, и это позволяет работать с ними единообразным образом на любых уровнях. Даже в ядре. (Даже C++EH в ядре.) Однако WINAPI поддерживает не только C++, поэтому возлагать на ОС прям вот C++EH шоколадно. Однако несложно реализовать трансляцию SEH в C++EH. Выше корявый, но пример. Что до ваших никсов, то это ваши сложности. У вас есть сигналы, вот с ними и ...думайте. Мне влом, не хватало ещё какой-нить в STM32 под realtime tiny os переносить его десяток исключений с парой десятков их источников. |
Сообщ.
#23
,
|
|
|
Цитата Qraizer @ Ты всё-таки определись, что ты хочешь. А я уже определился! Только одно прошу - давай ты без нервов, давай без них самих! =) В процессе обсуждения вопроса мы выявили два "важных" момента: 1) Обеспечение транзакционной целостности объектов - тут понятно и просто 2) Выброс стека вызовов при ловле исключений - тут (лично для меня пока не просто) Я все "почитаю и изучу". Ток одна просьба. Qraizer, не поднимай ни себе и не остальным нервы. Мы тут все более-менее на равных. Кто-то более компетентен, кто менее. Но в этом суть и соль общения. Очень тебя прошу, ты же профи. Держи себя в рамках, даже если к тебе обращаются специалисты гораздо низшего относительно тебя уровня! Добавлено Qraizer, да, кстати, да ... "Деление на нуль" - наверное одно, и наверное, единственное исключение, которое можно обозвать "аппаратным". Или не? Какие еще подобные исключения можно словить в "юзер-спейсе", которые не обрабатывала операционная система, а просто "вбросила"? И это не просто стёб, и не censored. Тут дело разработок. Просто скажи - вот они (список), или скажи "я погорячился". Прощу меня понять - мне важна суть, а не прав ты или не прав. Вообще на второе забей! Я триста раз могу ошибаться, но я тут чтобы получать достоверную инфу. Без обид! |
Сообщ.
#24
,
|
|
|
#AC и #BOUND (последнее давно не используется)
|
Сообщ.
#25
,
|
|
|
В плане дизайна обработки ошибок я бы сейчас рекомендовал использовать std::optional (иногда std::variant) и новенький std::expected.
Ну и именно исключения оставить на тот случай, когда совсем никак без них не обойтись (см. первое сообщение Qraizerа) А самое главное не забывать про т.н. гарантии безопасности исключений, введенные Саттером (или возможно Абрахамсом, но лично я впервые прочел у Саттера). Ну базовая, строгая и гарантия отсутствия исключений. Это достаточно легко гуглится, не вижу смысла тут писать подробности. Без понимания этих принципов будет очень сложно (невозможно?) написать качественный код с использованием исключений. |
![]() |
Сообщ.
#26
,
|
|
Цитата D_KEY @ Бери выше. Без этих принципов писать надёжный код вообще вряд ли получится, и без разницы, исключения или нет и на каком языке пишешь. Без понимания этих принципов будет очень сложно (невозможно?) написать качественный код с использованием исключений. |
![]() |
Сообщ.
#27
,
|
||||||||||||||||||||||||||
|
Majestio, если заглянуть в winnt.h, то там их вагон и маленькая тележка, штук 60. Не все они аппаратные, но все низкоуровневые. Типа STATUS_GUARD_PAGE_VIOLATION, STATUS_BREAKPOINT, STATUS_STACK_OVERFLOW итп. Конкретно аппаратных немного:
|
![]() |
Сообщ.
#28
,
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
P.S. У x86/64 исключений больше.
1) The UD2 instruction was introduced in the Pentium Pro processor. 2) Processors after the Intel386 processor do not generate this exception. 3) This exception was introduced in the Intel486 processor. 4) This exception was introduced in the Pentium processor and enhanced in the P6 family processors. 5) This exception was introduced in the Pentium III processor. |
Сообщ.
#29
,
|
|
|
Цитата Qraizer @ STATUS_FLOAT_DIVIDE_BY_ZERO Деление значения с плавающей запятой на 0,0. STATUS_FLOAT_OVERFLOW Превышение максимальной положительной экспоненты с плавающей запятой. STATUS_FLOAT_UNDERFLOW Превышение модуля наименьшей отрицательной экспоненты с плавающей запятой. STATUS_FLOATING_RESEVERED_OPERAND Использование зарезервированного формата с плавающей запятой (недопустимое использование формата). Вот эти 4 это просто флаги в fpu.StatusWord и как реальные Exception они не генерируются. Т.е. они софтверные и выбрасываются после проверки флага в регистре после fpu инструкции. |
Сообщ.
#30
,
|
|
|
Цитата Qraizer @ Majestio, если заглянуть в winnt.h, то там их вагон и маленькая тележка, штук 60. Не все они аппаратные, но все низкоуровневые. Типа STATUS_GUARD_PAGE_VIOLATION, STATUS_BREAKPOINT, STATUS_STACK_OVERFLOW итп. Конкретно аппаратных немного: ![]() Ну, положим, проверку деления на нуль можно делать, и нужно ... Но где и как делать проверку остального, к примеру STATUS_ILLEGAL_INSTRUCTION. Я даже не знаю - смогу ли я такое сгенерировать специально! Ну может быть какими-то ассемблерными вставками ... и то, не уверен. |