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

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


当前回答

我将从竞争性编程(cp)的角度给出我的答案,但它也适用于其他领域。

很多时候在做cp的时候,约束条件是相当大的。

例如:我有一个关于变量N, M, Q的问题,使得1≤N, M, Q < 10^5。

我犯的错误是我在c++中声明了一个大小为10000 x 10000的2D整数数组,并在Codechef中挣扎了近2天的SIGABRT错误。

现在,如果我们计算:

整数的典型大小:4字节 不。数组中的单元格:10000 x 10000 总大小(字节):400000000字节= 4*10^8≈400mb

你对这些问题的解决方案将在你的PC上工作(不总是),因为它可以负担得起这个大小。

但编码网站(在线裁判)的资源有限,只有几kb。

因此,会出现SIGABRT错误和其他此类错误。

结论:

在这样的问题中,我们不应该声明一个数组或向量或任何其他这种大小的DS,但我们的任务是使我们的算法如此高效,以至于它可以在没有它们(DS)或内存更少的情况下工作。

PS:这个错误可能有其他原因;上面是其中一个。

其他回答

关于第一个问题:在c++中进程获得SIGABRT的场景是什么?

我可以想到两种c++程序自动中止的特殊情况——不是通过直接调用std::abort()或std::terminate():

一:在处理异常时抛出异常。

try {
    throw "abc";
}
catch (...) {
    throw "def";  // abort here
}

二:试图在main()外部传播的未捕获异常。

int main(int argc, char** argv)
{
    throw "abc";  // abort here
}

c++专家可能还能举出更多的特殊情况。

在这些参考页面上也有很多好的信息:

https://en.cppreference.com/w/cpp/utility/program/abort https://en.cppreference.com/w/cpp/error/terminate

错误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,因为函数没有创建严格的弱顺序。删除=解决了问题。

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

string x[5];

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

    cin>>x[i];

}

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

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

杀死 -SIGABRT 30823

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

$ /bin/dash
$ Aborted

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

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

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

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

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

thread::join();

or

thread::detach();