SIGABRT 和 SIGSEGV 有什么区别
What is the difference between SIGABRT and SIGSEGV
我用下面两段代码造成了核心转储错误:
//test.cpp
int main()
{
int *p = new int;
*p = 100;
delete p;
delete p;
return 0;
}
//test2.cpp
int main()
{
int *p = new int;
*p = 100;
delete p;
*p = 111;
std::cout<<*p<<std::endl;
return 0;
}
Gdb 告诉我第一段代码因为信号 SIGABRT 而被核心转储,而第二段代码因为信号 SIGSEGV 而被核心转储。
你能说出有什么区别吗?
这两个例子都是未定义的行为,这意味着根据 c++,编译器(和系统)可以做任何它想做的事。
- 在情况 1 中,可能会检查指针的双重删除,因此发出
SIGABRT
信号。 SIGABRT
表示 异常终止条件,例如由 abort(). 发起
- 在情况 2 中,系统检测到您对已删除指针的尊重,并且
创建一个
SIGSEGV
信号。 SIGSEGV
表示 无效内存访问(分段错误)
但两者仍然是 UB,因此这只是您当前 compiler/os/system 的一个功能。从错误的定义中可以清楚地看出错误之间的区别here。一种是中止,通常由编译器或编码器生成。一种是由无效内存访问引起的,通常由操作系统或硬件发出信号。
两次删除指针是未定义的行为,这意味着任何事情都有可能发生。在这种情况下,它会导致发出 SIGABRT
信号。
访问不属于程序的内存也是未定义的行为,在这种情况下会导致分段错误并发出 SIGSEGV
。
SIGABRT
表示程序本身检测到错误并通过调用 abort
. 报告
SIGSEGV
表示对有效内存的无效访问。
SIGABRT 被显式检测并通过 delete 的实现发出信号,它检测到第二次删除无效。它是通过调用 abort 函数
启动的
SIGSEGV 不同,它是正在 而不是像以前那样通过库中的检查来检测,它是通过 OS 的内存管理启动的
我用下面两段代码造成了核心转储错误:
//test.cpp
int main()
{
int *p = new int;
*p = 100;
delete p;
delete p;
return 0;
}
//test2.cpp
int main()
{
int *p = new int;
*p = 100;
delete p;
*p = 111;
std::cout<<*p<<std::endl;
return 0;
}
Gdb 告诉我第一段代码因为信号 SIGABRT 而被核心转储,而第二段代码因为信号 SIGSEGV 而被核心转储。
你能说出有什么区别吗?
这两个例子都是未定义的行为,这意味着根据 c++,编译器(和系统)可以做任何它想做的事。
- 在情况 1 中,可能会检查指针的双重删除,因此发出
SIGABRT
信号。SIGABRT
表示 异常终止条件,例如由 abort(). 发起
- 在情况 2 中,系统检测到您对已删除指针的尊重,并且
创建一个
SIGSEGV
信号。SIGSEGV
表示 无效内存访问(分段错误)
但两者仍然是 UB,因此这只是您当前 compiler/os/system 的一个功能。从错误的定义中可以清楚地看出错误之间的区别here。一种是中止,通常由编译器或编码器生成。一种是由无效内存访问引起的,通常由操作系统或硬件发出信号。
两次删除指针是未定义的行为,这意味着任何事情都有可能发生。在这种情况下,它会导致发出 SIGABRT
信号。
访问不属于程序的内存也是未定义的行为,在这种情况下会导致分段错误并发出 SIGSEGV
。
SIGABRT
表示程序本身检测到错误并通过调用abort
. 报告
SIGSEGV
表示对有效内存的无效访问。
SIGABRT 被显式检测并通过 delete 的实现发出信号,它检测到第二次删除无效。它是通过调用 abort 函数
启动的SIGSEGV 不同,它是正在 而不是像以前那样通过库中的检查来检测,它是通过 OS 的内存管理启动的