Неуловимое пользовательское исключение C ++ - PullRequest
5 голосов
/ 25 июня 2011

Это сводило меня с ума всю ночь.

class ExceptionImpl;

/**
* Custom Exception.
*/
class Exception : public virtual std::exception
{
  public:
    Exception( const Exception& original );

    Exception( const std::string& message );

    virtual ~Exception( void ) throw( );

    virtual const char* what( void ) const throw( );

  private:
    const std::unique_ptr< ExceptionImpl > m_pimpl;
};

Я выбрасываю это пользовательское исключение из библиотеки следующим образом

throw Exception( "Error message" );

и ловлю его в основном через

try
{
   regex pattern(R"(a*)");

   Id::set_pattern_validator(pattern);

   assert(false);
}
catch( Exception const& exception )
{
   assert(true);
}

Id::set_pattern_validator - это статический метод в классе Id библиотеки и источник исключения.Я перепробовал все, что мог, чтобы поймать исключение, но его не удалось поймать.

catch( Exception )

catch( std::exception )

catch( ... )

Nada!

Вывод на терминал выглядит следующим образом.

"Прекращение вызывается после создания экземпляра« Exception ». What (): Валидатор шаблона нельзя изменить после установки. Прервать прерывание."

Теперь не нужно жертвоватькоза Я в растерянности от того, что делать дальше ... какие-либо советы / подсказки ???

Примечание: если я выбрасываю пользовательское исключение в main, я могу поймать его без проблем.

Среда Mac OS X с использованием GCC с поддержкой C ++ 0x.

РЕДАКТИРОВАТЬ: Решением на данный момент является продолжение разработки системы на основе Linux (Fedora).Я пока не буду принимать ответ.Спасибо всем за помощь.

Ответы [ 3 ]

6 голосов
/ 25 июня 2011

Если catch (...) (во вмещающей функции в том же потоке) не обрабатывает это, ваш сбой не вызван брошенным необработанным исключением в конце концов.

(Примечание. Исключение может быть вызвано и завершить работу программы, даже если бы она была перехвачена. Бросок из деструктора или нарушение условия throws - это два способа.)

0 голосов
/ 01 февраля 2013

У меня были похожие проблемы.

Я использовал QT на Mac OSX 10.8 (Mountain Lion), используя gcc47 (macports).Внутри QT main я вызвал метод из разделяемой библиотеки, который выдал исключение, определенное в этой разделяемой библиотеке.Независимо от того, какой тип try-catch я поместил вокруг вызова метода (перехват исключения, перехват базы или даже перехват (…)), всегда вызывался обработчик завершения, что приводило к прерыванию моей программы.Было невозможно поймать исключение.

Сначала я попробовал опцию -shared-libgcc во время компоновки.В противном случае это не было проблемой, предложение catch (…) сработало бы.

Затем я написал простой main без QT, используя рукописные make-файлы, связанные с общей библиотекой.И это сработало!

Я пришел к выводу, что проблема была вызвана различием опций, которые были переданы в gcc (то есть разницей между make-файлом, сгенерированным QT / qmake, и моим рукописным).

После некоторого бинарного поиска я обнаружил, что следующие проблемы вызывают мои проблемы (при соединении):

-mmacosx-version-min=10.5

После изменения на следующее:

-mmacosx-version-min=10.6,

все работало, как и ожидалось.

Я не знаю, почему указание опции для 10.6 решает проблему.Есть мысли по этому поводу?

0 голосов
/ 25 июня 2011

Если вы выбрасываете пользовательское исключение изнутри main и можете его перехватить, то вы должны показывать UB где-то в стеке вызовов, в результате чего более позднее исключение не будет перехвачено.

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