1. C++ / Говнокод #13071

    +14

    1. 1
    std::set_unexpected( [] () {} );

    Студия достала и не позволяла обрабатывать исключения, а они нужны были для демонстрации работы, в итоге навесил такой костыль и включил SEH исключения в параметрах компиляции.

    Запостил: maksim_ovcharik, 29 Мая 2013

    Комментарии (38) RSS

    • Почему студия не позволяет обрабатывать исключения?
      Ответить
      • Она сама их ловит и невозможно продолжить работу, даже если стоит try/catch, в общем я не знаю с чем связанно это, также и не особо разбираюсь в C++, но подобный костыль и включение опции при компиляции помог.
        Ответить
        • дивизион бай зеро, фпу эксепшен и прочее?
          Ответить
        • Дебаггер ловит или кто? Если дебаггер - то галочку в его настройках убери, чтобы не хапал исключения ДО отдачи их проге.
          Ответить
          • Галочку убирал, но там так же есть кнопка продолжить, жму продолжить и снова ловит тоже исключение. Написал эту строчку, и после нажатия "продолжить", программа продолжает работать.
            Ответить
            • Кстати SEH исключения и C++ исключения это совершенно разные вещи. То, что визуалка по доброте душевной транслирует SEH в с++ еще ничего не значит ;)

              P.S. А зачем программе намеренно устраивать access violation?
              Ответить
              • > визуалка по доброте душевной транслирует SEH в с++
                Не транслирует. Ты перепутал с Borland C++ Builder
                Ответить
                • Ну значит память мне изменяет. Мне казалось, что я в шестой вижуалке ловил ацесс виолейшн обычным крестоблядским трай-кетчем.
                  Ответить
                  • А что, ошибка доступа не должна ловиться крестоисключениями?
                    Ответить
                    • исключения из стандарта ничего не знают про прерывания или сигналы
                      Ответить
                      • Да, и это один из основопологающих принципов исключений, заложенных в дизайн этой возможности языка. Они не должны быть реакцией на асинхронные собития, включая прерывания и приходящие асинхронно сигналы. В таких случаях надо использовать другие средства.
                        Ответить
                    • Крестотрай крестоловит крестотолько крестоправославные крестоисключения крестовброшенные крестовбрасывалкой (throw).

                      Трансляция остальных ошибок в исключения - implementation defined.
                      Ответить
                      • А чё, автодеструкторы тоже по пизде идут?
                        Ответить
                        • причем тут они?
                          приложение работает как умеет - даже если оно однопоточное - и выглядит как последовательность инструкций

                          приложению приходит прерывание/сигнал, значит, основной поток приостанавливается на какой то своей инструкции, приложение обрабатывает сигнал, после обработки основной поток может продолжиться

                          если обработка сигнала подразумевает кончину - особенно, когда это происходит по умолчанию - никому не будет дела до того, что там происходит в основном потоке

                          т.е. если ты выделял память, захватывал ресурсы и открывал устройства, то операционная система за тебя это всё подчистит
                          если ты писал в свой файл и недописал, то файл закроется в том состоянии, в котором основной поток его оставил

                          это в общих словах
                          Ответить
                          • Ну хорошо, поделил я на ноль - и что, прога падает, что бы я ни делал?
                            Ответить
                            • ну конкретно с делением на ноль не всё так просто
                              везде рекомендуется из своего обработчика SIGFPE завершать процесс, иначе никто ничего не гарантирует
                              если его заигнорить, то скорее всего программа впадет в бесконечный цикл, т.к. деление на ноль на текущей инструкции будет происходить снова и снова
                              вроде бы отдельными телодвижениями можно получить user context в обработчике и сдвинуть instruction pointer, но я такого никогда не делал и воспроизводить, если честно, не очень интересно
                              Ответить
                              • Где-то я видел код, который транслировал сигналы в крестоэкцепшены путем байтоёбства и модификации стека.
                                Ответить
                                • просто тарас намекает, что, например, дельфи эту функциональность даёт из коробки, самостоятельно байтоёбствуя и преобразуя назойливую хуйню SIGFPE и SIGSEGV в нативные эксепшены в текущей области try/catch
                                  Ответить
                        • При некрестоблядских исключениях\сигналах - да. В большинстве случаев прога завершается без отработки деструкторов. Ну разве что вызовутся implementation defined функции, в которых эту ситуацию можно попытаться разрулить.
                          Ответить
              • Это даже не программа, а лаба
                http://pastebin.com/cDQQ98fF

                так же пробовал ловить через __try/__except, на сколько я понял они именно для этих целей созданы, в итоге получал предупреждение при компиляции и тоже самое при отлове.
                Ответить
                • А почему не преобразуешь в с++ исключение что-нибудь типа?
                  std::set_unexpected( [] () {throw THuinyaException;} ); чтобы потом обычным трай кечем поймать?
                  Ответить
                  • Для демонстрации достаточно же, преподу бы и вываливающиеся исключение в студии сошло бы, но для отчета решил сделать как то так.
                    Ответить
                    • Перепутал std::set_unexpected с SetUnhandledExceptionFilter (или как его там), но вижу ты меня понял.

                      PS: вспомнил правильное название:_set_se_translator
                      Ответить
                    • Вообще, в продакшене, обрабатывать access violation способами отличными от core dump'а и суицида нежелательно, ну разве что сохранить открытый документ в отдельный(!) файл, если прога занималась редактированием чего-то большого, что юзеру жалко потерять.

                      Если случился AV (обращение за границы стека, кучи, попытка прыжка в неисполняемую память и т.п.) - в проге явно что-то пошло не так, и исправить этот НЁХ программными средствами уже практически невозможно.

                      Вторая проблема поимки AV - оно совсем не гарантированно. Биты доступа расставляются на уровне страничек, не байтов. Поэтому прога может спокойно копаться в невыделенных кусках кучи и даже чуть-чуть за ней, или выполнять код, лежащий неподалеку от границы реального кода, и при этом творить всякую хуйню не поймав AV.

                      P.S. Для лабы сойдет ;)
                      Ответить
                      • Почему тебе не нравится поведение борланда, кидающнго исключения С++ при ав и ему подобном?
                        Ответить
                        • Да ради бога, пускай кидает. Я только о том, что программисту не стоит такие фатальные исключения подавлять и "продолжать работу". Та же самая фигня и с сигналами в линухе.
                          Ответить
                      • Благодаря вашим комментариям, понял в каком направлении гуглить, погуглил немного и понял суть данных исключений, как они обрабатываются и что к чему вообще. Думаю, что в будущем мне мало с виндой придется работать, но все равно спасибо.

                        upd: вашим, в смысле твоим и LispGovno
                        Ответить
            • >>программа продолжает работать.
              Я бы сказал "продолжает ковылять в страну неопределенного поведения". [mode=Ванга]Небось, еще и все предупреждения компилятора отключены.[/mode] Фу-фу-фу!
              Ответить
    • показать все, что скрытоСПЕРМОПРОБЛЕМЫ СПЕРМОКЛОУНА
      Ответить

    Добавить комментарий