在c++中,进程获得SIGABRT的场景是什么?这个信号总是来自进程内部还是可以从一个进程发送到另一个进程?

有没有办法确定是哪个进程在发送这个信号?


当前回答

在我的例子中,这是由于在一个数组中输入的一个索引等于数组的长度。

string x[5];

for(int i=1; i<=5; i++){

    cin>>x[i];

}

X[5]正在被访问,但不存在。

其他回答

进程从自身获取SIGABRT的情况: Hrvoje提到了一个从ctor调用的被掩埋的纯虚拟生成一个中止,我为此重新创建了一个例子。 这里,当要构造d时,它首先调用它的基类A ctor, 并将内部指针传递给自身。 在表被有效指针填满之前调用纯虚方法, 因为d还没有被构造。

#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;
}

编译:g++ -o aa aa.cpp

无限制

:运行。/ aa

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

现在让我们快速查看核心文件,并验证SIGABRT确实被调用:

gdb aa core

见规则:

i r
rdx            0x6      6
rsi            0x69a    1690
rdi            0x69a    1690
rip            0x7feae3170c37

校验码:

灾害学0 x7feae3170c37

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

:)

GNU libc将在调用abort()(然后触发SIGABRT)之前将有关一些致命条件的信息打印到/dev/tty,但是如果您将程序作为服务运行,或者不是在真正的终端窗口中运行,那么这些消息可能会丢失,因为没有tty来显示这些消息。

请参阅我关于将libc重定向到stderr而不是/dev/tty的帖子:

捕捉libc错误消息,从/dev/tty重定向

你可以使用kill(2)接口向任何进程发送任何信号:

杀死 -SIGABRT 30823

30823是我启动的一个破折号进程,所以我可以很容易地找到我想要终止的进程。

$ /bin/dash
$ Aborted

Aborted输出显然是dash报告SIGABRT的方式。

它可以使用kill(2)直接发送给任何进程,或者进程可以通过assert(3)、abort(3)或raise(3)将信号发送给自己。

在我的例子中,这是由于在一个数组中输入的一个索引等于数组的长度。

string x[5];

for(int i=1; i<=5; i++){

    cin>>x[i];

}

X[5]正在被访问,但不存在。

abort()向调用进程发送SIGABRT信号,这就是abort()的基本工作方式。

Abort()通常由库函数调用,用于检测内部错误或一些严重破坏的约束。例如,如果malloc()的内部结构被堆溢出破坏,它将调用abort()。