В чем разница между SIGABRT и SIGSEGV - PullRequest
0 голосов
/ 22 января 2019

Я сделал ошибку дампа ядра с двумя кодами выше:

//test.cpp
int main()
{
    int *p = new int;
    *p = 100;
    delete p;
    delete p;
    return 0;
}

//test2.cpp
int main()
{
    int *p = new int;
    *p = 100;
    delete p;
    *p = 111;
    std::cout<<*p<<std::endl;
    return 0;
}

Gdb сказал мне, что первый кусок кода был сброшен ядром из-за сигнала SIGABRT, тогда как второй кусок кодаядро сброшено из-за сигнала SIGSEGV.

Не могли бы вы сказать, в чем разница?

Ответы [ 3 ]

0 голосов
/ 22 января 2019

Удаление указателя дважды является неопределенным поведением, что означает, что может произойти все что угодно.В этом случае это приводит к выдаче сигнала SIGABRT.

Доступ к памяти, которая не принадлежит программе, также является неопределенным поведением, которое в этом случае приводит к ошибке сегментации и выдается SIGSEGV.

  • SIGABRT указывает на ошибку, обнаруженную самой программой и сообщаемую путем вызова abort.
  • SIGSEGV указывает на недопустимый доступ к действительной памяти.
0 голосов
/ 22 января 2019

SIGABRT явно обнаруживается и сигнализируется реализацией delete , которая обнаружила недействительность второго удаления. Он запускается путем вызова функции abort

SIGSEGV отличается, он проходит , а не обнаруживается проверкой в ​​библиотеке, как предыдущая, он запускается через управление памятью ОС

см. https://en.cppreference.com/w/c/program/SIG_types

0 голосов
/ 22 января 2019

Оба эти примера неопределенное поведение , это означает, что в соответствии с c ++ компилятор (и система) могут делать все, что захотят.

  • В случае 1, вероятно, есть проверка на двойное удаление указателя, поэтому сигнализируется SIGABRT. SIGABRT означает ненормальное условие завершения, как, например, инициировано abort () .
  • В случае 2 система обнаруживает вашу удаленность указателя и создает сигнал SIGSEGV. SIGSEGV означает неверный доступ к памяти (ошибка сегментации)

Но оба они по-прежнему UB, так что это просто особенность вашего текущего компилятора / ОС / системы. Разница между ошибками ясна из определения ошибок здесь . Одним из них является прерывание, обычно генерируемое компилятором или кодером. Одна из них вызвана неправильным доступом к памяти, обычно сообщаемым операционной системой или оборудованием.

...