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

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


当前回答

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

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

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

其他回答

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

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

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

在c++中还有另一个简单的原因。

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

例如,线程范围结束,但你忘记调用

thread::join();

or

thread::detach();

它通常发生在内存分配有问题的时候。

当我的程序试图分配一个 大小为负的数组。

libc和其他库通常使用SIGABRT在出现严重错误时中止程序。例如,glibc在检测到double-free或其他堆损坏时发送SIGABRT。

此外,大多数断言实现在断言失败的情况下使用SIGABRT。

此外,SIGABRT可以像其他信号一样从任何其他进程发送。当然,发送进程需要以相同的用户或根用户运行。

错误munmap_chunk无效指针也会导致SIGABRT,在我的情况下,它很难调试,因为我根本没有使用指针。事实证明,它与std::sort()有关。

Std::sort()需要一个比较函数来创建严格的弱排序!这意味着当a==b成立时,比较器(a, b)和比较器(b, a)都必须返回false。(参见https://en.cppreference.com/w/cpp/named_req/Compare)在我的例子中,我在我的结构中定义了操作符<,如下所示:

bool operator<(const MyStruct& o) const {
    return value <= o.value; // Note the equality sign
}

这导致了SIGABRT,因为函数没有创建严格的弱顺序。删除=解决了问题。