C ++ необработанные исключения - PullRequest
7 голосов
/ 23 сентября 2010

Предлагает ли C ++ способ «показать» что-то визуальное, если возникает необработанное исключение?

Я хочу сделать что-то вроде assert(unhandled exception.msg()), если это действительно произойдет (как в следующем примере):

void foo() {
   throw std::exception("Message!");
}

int main() {
 foo();
}

Я ожидаю, что этот вид кода не завершится немедленно (поскольку исключение не было обработано), скорее покажите пользовательское сообщение подтверждения (на самом деле Message!).

Это возможно?

Ответы [ 8 ]

11 голосов
/ 23 сентября 2010

В стандарте не указано, как на самом деле отобразить сообщение необработанного исключения.Однако на многих платформах это возможно в любом случае.В Windows вы можете использовать SetUnhandledExceptionFilter и извлечь информацию об исключениях из C ++.С g ++ (соответствующие версии в любом случае) обработчик завершения может получить доступ к неперехваченному исключению с помощью кода, подобного:

   void terminate_handler()
   {
       try { throw; }
       catch(const std::exception& e) { log(e.what()); }
       catch(...) {}
   }

, и действительно обработчик завершения по умолчанию в g ++ делает нечто похожее на это.Вы можете установить обработчик завершения с помощью set_terminate.

Короче говоря, нет никакого общего пути C ++, но есть способы, зависящие от вашей платформы.

6 голосов
/ 23 сентября 2010

Microsoft Visual C ++ позволяет перехватывать необработанные исключения C ++ , например, . Это стандартное поведение STL .

Вы устанавливаете обработчик посредством вызова на set_terminate. Рекомендуется, чтобы ваш обработчик не очень много работал, а затем завершил программу, но я не понимаю, почему вы не могли сигнализировать что-то через assert - хотя у вас нет доступа к исключению, вызвавшему проблему. *

4 голосов
/ 23 сентября 2010

Я думаю, что вы бы получили выгоду от всеобъемлющего заявления следующим образом:

int main() {
 try {
   foo();
 catch (...) {
   // Do something with the unhandled exception.
 }
}
4 голосов
/ 23 сентября 2010

Если вы используете Windows, хорошая библиотека для обработки необработанных исключений и сбоев - CrashRpt .Если вы хотите сделать это вручную, вы также можете использовать следующее, что я написал в этом ответе .

1 голос
/ 23 сентября 2010

Да, это возможно.Вот, пожалуйста:

#include <iostream>
#include <exception>

void foo() 
{
   throw std::exception("Message!");
}

int main() 
{
  try
  {
    foo();
  }
  catch (std::exception& e)
  {
    std::cout << "Got exception: " << e.what() << std::endl;
  }

  return 0;
}
1 голос
/ 23 сентября 2010

Если я правильно читаю ваш вопрос, вы спрашиваете, можете ли вы перегрузить throw (изменяя его поведение по умолчанию), чтобы он что-то определял пользователем. Нет, ты не можешь.

Редактировать: поскольку вы настойчивы :), вот вам плохая идея ™:

#include <iostream>
#include <stdlib.h>
#include <windows.h>

void monkey() {
   throw std::exception("poop!");
}

LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter) {
    std::cout << "poop was thrown!" << std::endl;
    return EXCEPTION_EXECUTE_HANDLER;
  }

int main() {
    SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
    monkey();
    return 1;
}

Опять же, это очень плохая идея, и она, очевидно, зависит от платформы, но она работает.

0 голосов
/ 23 сентября 2010

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

0 голосов
/ 23 сентября 2010

Стандарт c ++ - это обработчик завершения - как уже говорили другие

Если вам нужна лучшая отслеживаемость для бросков, то это то, что мы делаем

У нас есть макрос Throw, который регистрирует файлимя и номер строки и сообщение, а затем бросает.Требуется сообщение varargs в стиле printf.

Throw(proj::FooException, "Fingle %s unable to process bar %d", fingle.c_str(), barNo);

Я получаю хорошее сообщение журнала

Throw FooException from nargle.cpp:42 Fingle barf is unable to process bar 99
...