Ошибки обработки исключений в C ++ - PullRequest
0 голосов
/ 29 августа 2011

Я довольно хорошо справляюсь с обработкой исключений в C / C ++ - я знаю все о создании пользовательских классов из std :: exception, когда бросать, когда прибегать к более простым вещам, таким как UNIX errno и т. Д. но я всегда немного волнуюсь, когда дело доходит до доступа к коду COTS.

Если я вызываю функцию из библиотеки COTS следующим образом:

void DoSomething()
{
    try
    {
        CallCotsFunction();
    }
    catch (CotsException& ce)
    {
        //Cots error caught
    }
    catch (...)
    {
        //Unknown error caught.
    }
}

Если CallCotsFunction() имеет плохую обработку исключений или не обрабатывает исключение и выполняет деление на ноль или что-то еще, будет ли оно распространено вплоть до моих обработчиков исключений?

Если CallCotsFunction() вызывает sig-11 или что-то в этом роде, его поймают или все ставят на что-то столь серьезное?

Ответы [ 3 ]

6 голосов
/ 29 августа 2011

В Linux сигналы unix обычно не запускают обработчики исключений. Кроме того, вообще говоря, небезопасно выбрасывать исключение из обработчика сигнала (как минимум, вы должны скомпилировать с -fnon-call-exceptions; даже тогда я видел смешанные отчеты).

Обратите внимание, что вы всегда должны ловить исключения по ссылке, чтобы избежать нарезки:

catch (CotsException &ce)
{
  // ...
}

Вкратце: если ваша сторонняя библиотека позволяет распространению исключения C ++ без перехвата, да, это ударит по вашему приложению. Если он получен из std :: exception или другого распространенного типа, вы должны быть в состоянии его перехватить. Если это какой-то внутренний тип, который вам не доступен, вы не сможете поймать его по имени (но catch (...) должен его поймать). Исключения процессора (деление на ноль, ошибки сегмента и т. Д.) Не будут автоматически вызывать исключения C ++, если только вы или библиотека не установите обработчик сигнала для его преобразования; в этом случае код, запускающий сигнал, ДОЛЖЕН быть собран с -fnon-call-exceptions, чтобы стек работал для правильной работы.

Как правило, если библиотека вызывает ошибку, такую ​​как SIGFPU или SIGSEGV, результаты попытки восстановления с исключением являются непредсказуемыми; библиотека может не ожидать, что она размотает свой стек в этот момент, и с SIGSEGV вы можете иметь повреждение кучи, которое приводит к сбою самой системы исключения. Я бы не советовал пытаться восстановиться таким способом - просто позвольте процессу умереть.

0 голосов
/ 29 августа 2011

Любое исключение, не пойманное функцией, будет распространяться до вызывающей стороны. Должен ли вызывающий абонент беспокоиться о том, чтобы поймать такое исключение, это другой вопрос, и он зависит от , может ли вызывающий абонент разумно что-либо с этим делать . Например, если функция делится на ноль и из этого происходит исключение, в каком состоянии было все остальное? Если вы не знаете, то стоит ли вообще разрешать программе продолжаться?

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

0 голосов
/ 29 августа 2011

Сигналы не зависят от исключений C ++ и предшествуют им.

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

Я бы не предлагал выдавать исключение C ++ из обработчика сигнала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...