¿Cuándo un proceso obtiene SIGABRT (señal 6)?

¿Cuáles son los escenarios donde un proceso obtiene un SIGABRT en C ++? ¿Esta señal siempre proviene del proceso o puede enviarse esta señal de un proceso a otro?

¿Hay alguna manera de identificar qué proceso está enviando esta señal?

abort() envía al proceso de llamada la señal SIGABRT , así es como funciona abort() básicamente.

abort() suele ser llamado por las funciones de la biblioteca que detectan un error interno o alguna restricción gravemente dañada. Por ejemplo, malloc() llamará a abort() si sus estructuras internas están dañadas por un desbordamiento de stack.

Puede enviar cualquier señal a cualquier proceso utilizando la interfaz kill(2) :

kill -SIGABRT 30823

30823 fue un proceso de dash que comencé, así que pude encontrar fácilmente el proceso que quería matar.

 $ /bin/dash $ Aborted 

El resultado Aborted es aparentemente cómo dash informa un SIGABRT.

Se puede enviar directamente a cualquier proceso utilizando kill(2) , o un proceso puede enviar la señal a sí mismo a través de assert(3) , abort(3) o raise(3) .

SIGABRT es comúnmente utilizado por libc y otras bibliotecas para abortar el progtwig en caso de errores críticos. Por ejemplo, glibc envía un SIGABRT en caso de una corrupción detectada de doble libre u otra corrupción de montón.

Además, la mayoría de las implementaciones assert hacer uso de SIGABRT en caso de una afirmación fallida.

Además, SIGABRT se puede enviar desde cualquier otro proceso como cualquier otra señal. Por supuesto, el proceso de envío debe ejecutarse como el mismo usuario o raíz.

Suele suceder cuando hay un problema con la asignación de memoria.

Me pasó a mí cuando mi progtwig intentaba asignar una matriz con tamaño negativo.

Hay otra causa simple en el caso de c ++.

 std::thread::~thread{ if((joinable ()) std::terminate (); } 

es decir, el scope del hilo terminó pero olvidó llamar

 thread::join(); 

o

 thread::detach(); 

La libc de GNU imprimirá información en /dev/tty respecto a algunas condiciones fatales antes de llamar a abort() (que luego desencadena SIGABRT ), pero si está ejecutando su progtwig como un servicio o no en una ventana de terminal real, estos mensajes puede perderse, porque no hay tty para mostrar los mensajes.

Ver mi publicación sobre cómo redirigir libc para escribir en stderr en lugar de / dev / tty:

Captura de mensajes de error de libc, redirigiendo desde / dev / tty

Un caso cuando el proceso obtiene SIGABRT de sí mismo: Hrvoje mencionó acerca de un ser virtual puro enterrado llamado desde ctor que genera un aborto, recreé un ejemplo para esto. Aquí cuando se va a construir d, primero llama a su clase base A ctor, y pasa el puntero interno a sí mismo. el Actor llama al método virtual puro antes de que la tabla se llenara con un puntero válido, porque d aún no está construido.

 #include using namespace std; class A { public: A(A *pa){pa->f();} virtual void f()=0; }; class D : public A { public: D():A(this){} virtual void f() {cout<<"D::f\n";} }; int main(){ D d; A *pa = &d; pa->f(); return 0; } 

comstackr: g ++ -o aa aa.cpp

ulimit -c ilimitado

ejecutar: ./aa

 pure virtual method called terminate called without an active exception Aborted (core dumped) 

ahora veamos rápidamente el archivo central y validemos que efectivamente se llamó SIGABRT:

 gdb aa core 

ver reglas:

 ir rdx 0x6 6 rsi 0x69a 1690 rdi 0x69a 1690 rip 0x7feae3170c37 

Código de verificación:

disas 0x7feae3170c37

 mov $0xea,%eax = 234 <- this is the kill syscall, sends signal to process syscall <----- 

http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

234 sys_tgkill pid_t tgid pid_t pid int sig = 6 = SIGABRT

🙂

En mi caso, fue debido a una entrada en una matriz en un índice igual a la longitud de la matriz.

 string x[5]; for(int i=1; i<=5; i++){ cin>>x[i]; } 

x [5] se está accediendo que no está presente.

Intereting Posts