Как обрабатывать сигнал SIGABRT?
Вот код, на котором я установил свой обработчик для SIGABRT
Сигнал тогда я звоню abort()
но обработчик не срабатывает, а программа прерывается, почему?
#include <iostream>
#include <csignal>
using namespace std;
void Triger(int x)
{
cout << "Function triger" << endl;
}
int main()
{
signal(SIGABRT, Triger);
abort();
cin.ignore();
return 0;
}
ПРОГРАММНЫЙ ВЫХОД:
3 ответа
Как уже говорили другие, вы не можете получить возврат abort() и позволить продолжить выполнение в обычном режиме. Однако вы можете защитить фрагмент кода, который может вызвать прерывание, с помощью структуры, похожей на попытку catch. Выполнение кода будет прервано, но остальная часть программы может продолжаться. Вот демо:
#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <iostream>
jmp_buf env;
void on_sigabrt (int signum)
{
longjmp (env, 1);
}
void try_and_catch_abort (void (*func)(void))
{
if (setjmp (env) == 0) {
signal(SIGABRT, &on_sigabrt);
(*func)();
}
else {
std::cout << "aborted\n";
}
}
void do_stuff_aborted ()
{
std::cout << "step 1\n";
abort();
std::cout << "step 2\n";
}
void do_stuff ()
{
std::cout << "step 1\n";
std::cout << "step 2\n";
}
int main()
{
try_and_catch_abort (&do_stuff_aborted);
try_and_catch_abort (&do_stuff);
}
Хотя вы можете заменить обработчик для SIGABRT
а также abort()
обратит внимание на обработчик, прерывание будет заблокировано, только если обработчик сигнала не вернется. Соответствующая цитата в C99 находится в 7.20.4.1 параграфе 2:
Функция прерывания вызывает аварийное завершение программы, если только сигнал SIGABRT не перехватывается и обработчик сигнала не возвращается....
Ваш обработчик сигнала возвращается, и, следовательно, программа прерывается.
Вы получаете эти симптомы, то есть всплывающее диалоговое окно отладки, когда у вас есть отладочная сборка (с окнами и Visual Studio- я тестирую с версией 2012), поскольку она устанавливает разрыв отладки в реализации отладки abort()). Если вы выберете "игнорировать", вы получите сообщение "Функциональный триггер"
Если вы делаете сборку релиза, вы не получаете всплывающее диалоговое окно отладки, и вы получаете сообщение, как и ожидалось