Как обрабатывать сигнал SIGABRT? - PullRequest
7 голосов
/ 20 января 2012

Вот код, для которого я установил свой обработчик для сигнала 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;
}

ВЫХОД ПРОГРАММЫ:

enter image description here

Ответы [ 3 ]

14 голосов
/ 20 января 2012

Как уже говорили другие, вы не можете вернуть abort () и разрешить нормальное выполнение. Однако вы можете защитить кусок кода, который может вызвать прерывание, с помощью структуры, похожей на попытку catch. Выполнение кода будет прервано, но остальная часть программы может продолжаться. Вот демо:

#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <iostream>

jmp_buf env;

void on_sigabrt (int signum)
{
  signal (signum, SIG_DFL);
  longjmp (env, 1);
}

void try_and_catch_abort (void (*func)(void))
{
  if (setjmp (env) == 0) {
    signal(SIGABRT, &on_sigabrt);
    (*func)();
    signal (SIGABRT, SIG_DFL);
  }
  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);
}
7 голосов
/ 20 января 2012

Хотя вы можете заменить обработчик на SIGABRT и abort() обратит внимание на обработчик, прерывание будет заблокировано только в том случае, если обработчик сигнала не вернется. Соответствующая цитата в C99 находится в 7.20.4.1 параграфе 2:

Функция прерывания вызывает аварийное завершение программы, если только сигнал SIGABRT не перехватывается и обработчик сигнала не возвращается. ...

Ваш обработчик сигналов возвращается, и, следовательно, программа прерывается.

2 голосов
/ 21 октября 2015

Вы получаете эти признаки, например всплывающее диалоговое окно отладки, когда у вас есть отладочная сборка (с окнами и Visual Studio - я тестирую с версией 2012 года), поскольку она устанавливает разрыв отладки в реализации отладки abort ()).Если вы выберете «игнорировать», вы получите это сообщение «Функциональный триггер»

Если вы выполните сборку релиза, вы не получите всплывающее диалоговое окно отладки и получите сообщение, как и ожидалось

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