首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么恐慌时恐慌会导致非法指令?

为什么恐慌时恐慌会导致非法指令?
EN

Stack Overflow用户
提问于 2021-09-26 01:13:49
回答 1查看 641关注 0票数 3

考虑以下故意造成双重恐慌的代码:

代码语言:javascript
运行
复制
use scopeguard::defer; // 1.1.0

fn main() {
    defer!{ panic!() };
    defer!{ panic!() };
}

我知道这通常发生在Drop实现恐慌时,而不是以前的恐慌中,但是为什么它会导致程序发出非法指令呢?这听起来像是代码被破坏了,或者跳转到了某个意想不到的地方。我认为这可能与系统或代码生成有关,但我在各种平台上进行了测试,它们都发出类似的错误,原因是相同的:

  • Linux: 线惊慌失措。流产。非法指令(核心倾弃)
  • Windows (与cargo run一起): 线惊慌失措。流产。错误:进程没有成功退出:target\debug\tests.exe (退出代码: 0xc000001d,STATUS_ILLEGAL_INSTRUCTION)
  • 铁锈游乐场: 线惊慌失措。流产。超时:被监视的命令转储核心/操场/工具/entrypoint.sh:第11: 8行非法指令超时-信号=杀死${ timeout } "$@“

到底怎么回事?这是什么原因?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-26 01:13:49

这种行为是有意的。

来自评论的乔纳斯在为什么一滴中的恐慌会导致SIGILL?中的成就

它调用intrinsics::abort(),LLVM将其转换为ub2指令,这是非法的,因此

我找不到关于如何处理双重恐慌的任何文档,但是std::intrinsics::abort()的一个段落与此行为一致:

intrinsics::abort的当前实现是在大多数平台上调用无效指令。在Unix上,进程可能会以SIGABRTSIGILLSIGTRAPSIGSEGVSIGBUS等信号终止。准确的行为没有得到保证,也不稳定。

奇怪的是,这种行为与调用std::process::abort()不同,后者总是以SIGABRT结尾。

在x86上选择的非法指令是UD2 (我认为是上面注释中的一个错误)。一个矛盾的保留和文档化的未定义指令,而不是一条指令。因此,没有腐败或无效的跳转,只是一种快速和响亮的方式告诉操作系统,某些事情已经非常错误。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69331112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档