Неперехваченное исключение ведет себя по-разному для основного потока и другого std :: thread.
вот тестовая программа
#include <thread>
class XXX{
public:
XXX(){std::fprintf(stderr, "XXX ctor\n");}
~XXX(){std::fprintf(stderr, "XXX dtor\n");}
};
void mytest(int i)
{
XXX xtemp;
throw std::runtime_error("Hello, world!");
}
int main(int argc, char *argv[])
{
if(argc == 1) {
mytest(0);
}else{
std::thread th([&]{mytest(0);});
th.join();
}
}
приведенный выше код (C ++ 11), скомпилированный GCC 5.4, запускается без аргументов
XXX ctor
terminate called after throwing an instance of 'std::runtime_error'
what(): Hello, world!
Aborted (core dumped)
запустить 1 аргумент:
XXX ctor
XXX dtor
terminate called after throwing an instance of 'std::runtime_error'
what(): Hello, world!
Aborted (core dumped)
Итак, раскрутка стека выполняется в рабочем потоке, но не в основном потоке, ПОЧЕМУ?
Я спрашиваю, потому что я хотел бы, чтобы дамп ядра давал полезную информацию о трассировке стека в обоих случаях (для неперехваченного исключения).
Заранее спасибо!!!
Дальнейшие испытания показывают, что добавление ключевого слова noexcept в тело функции потока mytest () может частично решить мою проблему, потому что раскрутка не удастся, но это не лучшее решение, потому что раскрутка все равно будет частично происходить, если mytest () вызывает другой функция без гарантии noexcept и фактически сгенерировала неперехваченное исключение.
Обновление: спасибо всем поставщикам комментариев, теперь я понимаю, что исключение C ++ не поддерживает обратную трассировку, и GCC, как реализация C ++, имеет свободу выбора не раскручиваться, когда неперехваченное исключение выбрасывается из основного потока, и раскручиваться, когда из рабочего потока.
Обновление: особая благодарность Сиду С и Джайву Дадсону, я должен перепутать некоторые концепции: 1) обработка исключений / ошибок; 2) утверждение во время выполнения 3) Ошибка сегмента, 2 и 3 аналогичны, они являются невосстановимыми ошибками, немедленное прерывание - единственный выбор, они также удобны для обратной трассировки в отладчике, потому что раскрутка стека не задействована. они вообще не должны реализовываться с использованием концепции исключений. Предполагается, что исключение будет перехвачено всегда, позвольте неперехваченному исключению, оставить main () не рекомендуется.