Un caso in cui il processo ottiene SIGABRT da solo: Hrvoje ha menzionato un seppellimento di un vero e proprio virtuale sepolto dal generatore che ha generato un annullamento, ho ricreato un esempio per questo. Qui quando d deve essere costruito, prima chiama la sua classe base A ctor, e passa all'interno del puntatore a se stesso. l'A ctor chiama il metodo virtuale puro prima che la tabella fosse riempita con un puntatore valido, perché d non è ancora stato costruito.
#include<iostream>
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;
}
compilazione: g ++ -o aa aa.cpp
ulimit -c unlimited
run: ./aa
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
Ora consente di vedere rapidamente il file core, e convalidare SIGABRT è stato effettivamente chiamato:
gdb aa core
vedere REGS: codice
i r
rdx 0x6 6
rsi 0x69a 1690
rdi 0x69a 1690
rip 0x7feae3170c37
controllo:
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
:)
fonte
2017-03-29 08:20:11
Ci sono un paio di modi. Il modo più semplice, se hai scritto il programma, è quello di registrare un gestore di segnali per SIGABRT che stampi tali informazioni e ne scarichi i flussi prima di tornare. Il secondo modo più semplice è eseguire il programma all'interno di strace. Il terzo modo più semplice è assicurarsi che il programma generi un file core quando si blocca e scoprirlo tramite il core dump. –