RUST_BACKTRACE是什么意思?它有什么作用?

10

我的程序出现了panic,所以我按照它的建议运行了RUST_BACKTRACE=1,然后得到了以下结果(仅摘录一小部分)。

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行吗?
整个回溯信息都在这张图片上,复制粘贴到这里会很混乱。

enter image description here

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


好的,我解决了。它在第334行。无论如何,如果您愿意,您应该发布一个答案,我会选择您的答案作为最佳答案。 - boss revs
1个回答

15

什么是堆栈跟踪?

如果您的程序发生崩溃,说明遇到了错误并希望进行修复;此时堆栈跟踪可以帮助您。当发生崩溃时,您需要知道引起崩溃的原因(即触发崩溃的函数)。但通常直接触发崩溃的函数并不能真正显示出问题所在。因此,我们还需打印出调用前一个函数的函数……以此类推。我们追踪所有导致崩溃的函数调用直至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),则默认情况下会禁用调试符号,因为它们会增加可执行文件的大小并且通常对最终用户不重要。您可以在特定的profile部分中使用debug关键字来调整是否需要调试符号。

所有这些奇怪的函数是什么?!

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

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


堆栈跟踪怎么办?(tl;dr)

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

1
Rust回溯正在变得越来越好。点击此处了解更多信息。 - Pavel Strakhov
@PavelStrakhov 很甜 :3 目前的回溯信息相当... 丑陋。一旦这个稳定版本发布,我会更新我的答案,大约需要两周时间(我想)。 - Lukas Kalbertodt

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