当恐慌钩子发生恐慌时会发生什么?

4
std::panic::set_hook函数传入的函数如果发生了panic,会有什么后果?
有多种处理方式,例如将其视为未定义行为、像C++一样终止程序(参考链接)、为新的panic再次调用panic处理器、或是简单地中止hook的执行…… Rust在这里承诺了什么?
背景:我正在使用Rust/WASM编写Web应用程序,并希望创建一个panic hook,将任何错误发送到服务器进行调试。这涉及到网络操作,本身也可能失败。因此,我正在尝试弄清楚如何确保在这种双重故障情况下的某些合理行为。

3
查看源代码(https://doc.rust-lang.org/src/std/panicking.rs.html#658),如果钩子出现故障,进程将被终止。有一个panick_count在恐慌之后递增,如果再次递增,则会收到错误消息,指出钩子已经发生了故障,并且进程将被终止。 - Bamontan
1
@Bamontan 我也刚发现这个问题,回来起草一个答案。 :) - cdhowie
@cdhowie 把它变成一个答案,我太懒了不想做。 - Bamontan
1个回答

6

这并没有在源代码之外进行记录。

std中的恐慌入口点的源代码有这样的注释:

// If this is the third nested call (e.g., panics == 2, this is 0-indexed),
// the panic hook probably triggered the last panic, otherwise the
// double-panic check would have aborted the process. In this case abort the
// process real quickly as we don't want to try calling it again as it'll
// probably just panic again.

因此,对于您的问题的答案是:根据挂钩已经发生的恐慌次数,“再次调用恐慌处理程序以处理新的恐慌”或“终止程序”。
这一切都假设您没有使用#![no_std]。如果您使用了该属性,则要么完全禁用了恐慌,要么使用了#[panic_handler]自己实现了恐慌处理程序,在这种情况下,您可以自行决定会发生什么。

可以说这是双重panic,已被记录下来(我想?我能找到的唯一来源是https://rust-lang.github.io/rfcs/1328-global-panic-handler.html,但我记得看到有关它的文档)。 - Chayim Friedman
@ChayimFriedman 我不确定RFC中的术语是否与OP所问的完全吻合。RFC谈论了panic handler,但OP询问的是panic hook。panic hook是由std提供的一种工具,而不是语言,并且它是从panic handler中调用的。RFC表示任何双重panic都会导致中止,但是std中的panic handler具有明确处理双重panic的逻辑,这意味着要么std在某种程度上抑制了panic运行时的自动中止部分,要么panic运行时实际上没有自动中止,或者std不必要地防范双重panics。 - cdhowie
@ChayimFriedman(或者我误解了什么,这不是第一次了。) - cdhowie
我指的是句子"If a thread panics while panicking (a "double panic"), the panic handler will not be invoked and the process will abort"。唯一的问题是当线程在运行panic hook时是否被认为正在处于panic状态,而我的答案是肯定的。 - Chayim Friedman
@ChayimFriedman,这就需要我们问一下为什么标准库的panic处理程序会考虑到双重panic,而似乎panic运行时已经做了这个。 - cdhowie
RFC并没有说明这将是处理此事的紧急运行时。 - Chayim Friedman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接