Un cas où le processus obtient SIGABRT de lui-même: Hrvoje mentionné à propos d'un être virtuel pur enterré appelé de ctor générant un abandon, j'ai recréé un exemple pour cela. Ici, lorsque d doit être construit, il appelle d'abord sa classe de base A ctor, et passe à l'intérieur du pointeur vers lui-même. A ctor appelle la méthode virtuelle pure avant que la table ait été remplie avec un pointeur valide, car d n'est pas encore construit.
#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;
}
compilation: g ++ -o aa aa.cpp
ulimit -c reproductions illimité
: ./aa
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
Voyons maintenant rapidement le fichier de base, et valider que SIGABRT était en effet appelé:
gdb aa core
voir regs:
i r
rdx 0x6 6
rsi 0x69a 1690
rdi 0x69a 1690
rip 0x7feae3170c37
code de contrôle:
CEIQ 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
:)
Il existe plusieurs façons. Le plus simple, si vous avez écrit le programme, est d'enregistrer un gestionnaire de signal pour SIGABRT qui imprime ces informations et vide ses flux avant de revenir. Le deuxième moyen le plus simple consiste à exécuter le programme dans l'interface. Le troisième moyen le plus simple consiste à s'assurer que le programme génère un fichier de base lorsqu'il se bloque et de le découvrir via le vidage du noyau. –