考虑以下故意造成双重恐慌的代码:
use scopeguard::defer; // 1.1.0
fn main() {
defer!{ panic!() };
defer!{ panic!() };
}
我知道这通常发生在Drop
实现恐慌时,而不是以前的恐慌中,但是为什么它会导致程序发出非法指令呢?这听起来像是代码被破坏了,或者跳转到了某个意想不到的地方。我认为这可能与系统或代码生成有关,但我在各种平台上进行了测试,它们都发出类似的错误,原因是相同的:
cargo run
一起):
线惊慌失措。流产。错误:进程没有成功退出:target\debug\tests.exe
(退出代码: 0xc000001d,STATUS_ILLEGAL_INSTRUCTION)到底怎么回事?这是什么原因?
发布于 2021-09-26 01:13:49
这种行为是有意的。
来自评论的乔纳斯在为什么一滴中的恐慌会导致SIGILL?中的成就
它调用
intrinsics::abort()
,LLVM将其转换为ub2
指令,这是非法的,因此
我找不到关于如何处理双重恐慌的任何文档,但是std::intrinsics::abort()
的一个段落与此行为一致:
intrinsics::abort
的当前实现是在大多数平台上调用无效指令。在Unix上,进程可能会以SIGABRT
、SIGILL
、SIGTRAP
、SIGSEGV
或SIGBUS
等信号终止。准确的行为没有得到保证,也不稳定。
奇怪的是,这种行为与调用std::process::abort()
不同,后者总是以SIGABRT
结尾。
在x86上选择的非法指令是UD2
(我认为是上面注释中的一个错误)。一个矛盾的保留和文档化的未定义指令,而不是一条指令。因此,没有腐败或无效的跳转,只是一种快速和响亮的方式告诉操作系统,某些事情已经非常错误。
https://stackoverflow.com/questions/69331112
复制相似问题