【问题标题】:What is RUST_BACKTRACE supposed to tell me?RUST_BACKTRACE 应该告诉我什么?
【发布时间】:2017-04-11 02:46:22
【问题描述】:

我的程序惊慌失措,所以我按照它的建议运行RUST_BACKTRACE=1,我得到了这个(只是一点点sn-p)。

1: 0x800c05b5 - std::sys::imp::backtrace::tracing::imp::write::hf33ae72d0baa11ed
            at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42

2: 0x800c22ed - std::panicking::default_hook::{{closure}}::h59672b733cc6a455
            at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:351

如果程序恐慌它会停止整个程序,那么我在哪里可以确定它在哪一行发生恐慌?

这行是否告诉我第 42 行和第 351 行有问题?

整个回溯都在这张图片上,我觉得复制粘贴到这里会很麻烦。

我从未听说过堆栈跟踪或回溯。我正在编译警告,但我不知道调试符号是什么。

【问题讨论】:

  • 好吧,我想通了。它在 334 gg 线上。无论如何,你应该发布一个答案,如果你愿意,我会给你最好的答案。

标签: debugging rust backtrace panic


【解决方案1】:

什么是堆栈跟踪?

如果您的程序出现紧急情况,您遇到了错误并想修复它;堆栈跟踪希望在这里为您提供帮助。当恐慌发生时,您想知道恐慌的原因(触发恐慌的函数)。但是直接触发恐慌的函数通常不足以真正看到发生了什么。因此,我们还打印调用前一个函数的函数......等等。我们将所有导致恐慌的函数调用追溯到main(),这(几乎)是第一个被调用的函数。

什么是调试符号?

当编译器生成机器代码时,它几乎只需要为 CPU 发出指令。问题是几乎不可能快速看出一组指令来自哪个 Rust 函数。因此,编译器可以将附加信息插入到可执行文件中,这些信息会被 CPU 忽略,但会被调试工具使用。

一个重要的部分是文件位置:编译器在哪一行注释了哪条指令来自哪个文件。这也意味着我们稍后可以看到特定函数的定义位置。如果我们没有调试符号,我们就不能。

在您的堆栈跟踪中,您可以看到一些文件位置:

1: 0x800c05b5 - std::sys::imp::backtrace::tracing::imp::write::hf33ae72d0baa11ed
        at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42

Rust 标准库附带调试符号。因此,我们可以看到函数的定义位置(gcc_s.rs 第 42 行)。

如果您在调试模式下编译(rustccargo build),默认情况下会激活调试符号。但是,如果您在发布模式下编译(rustc -Ocargo build --release),则默认情况下会禁用调试符号,因为它们会增加可执行文件的大小,并且...通常对最终用户并不重要。您可以使用debug 键调整是否要在特定profile section 中的Cargo.toml 中调试符号。

这些奇怪的功能是什么?!

当您第一次查看堆栈跟踪时,您可能会对所看到的所有奇怪的函数名称感到困惑。别担心,这很正常!您对您的代码的哪一部分触发了恐慌感兴趣,但堆栈跟踪显示了所有涉及的函数。在您的示例中,您可以忽略前 9 个条目:这些只是处理恐慌并生成您所看到的确切消息的函数。

条目 10 仍然不是您的代码,但也可能很有趣:恐慌是在您使用 [] 运算符时调用的 Vec<T>index() 函数中触发的。最后,条目 11 显示了 you 定义的函数。但是您可能已经注意到,该条目缺少文件位置...以上部分描述了如何解决该问题。


如何处理堆栈跟踪? (tl;博士)

  1. 激活调试符号(如果您还没有)(例如,只需在调试模式下编译)。
  2. 忽略堆栈跟踪顶部 stdcore 中的任何函数
  3. 查看您定义的第一个函数,在您的文件中找到相应位置并修复错误。
  4. 如果您还没有,请将所有 camelCase 函数和方法名称更改为 snake_case,以遵守社区范围的样式指南。

【讨论】:

  • Rust 回溯are getting better.
  • @PavelStrakhov Sweet :3 当前的回溯痕迹相当...丑陋。一旦达到稳定状态,我将更新我的答案,这应该是 2 周内(我认为)。