我的程序恐慌,所以我按照它的建议运行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行有问题吗?
整个回溯都在这张图像上,我觉得将其复制并粘贴到此处很麻烦。
我从未听说过堆栈跟踪或反向跟踪。我正在编译警告,但是我不知道什么是调试符号。
如果您的程序出现紧急情况,则说明您遇到了一个错误并想修复它。堆栈跟踪希望在这里为您提供帮助。发生紧急情况时,您想知道发生紧急情况的原因(触发紧急情况的功能)。但是直接引发恐慌的功能通常不足以真正了解正在发生的事情。因此,我们还打印了调用前一个函数的函数……等等。我们回溯所有导致崩溃的函数调用,该恐慌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行)。
如果您在调试模式下(rustc
或cargo build
)进行编译,则默认情况下会激活调试符号。但是,如果您以发布模式(rustc -O
或cargo build --release
)进行编译,则调试符号默认情况下处于禁用状态,因为它们会增加可执行文件的大小,并且...通常对于最终用户而言并不重要。您可以使用键Cargo.toml
在特定profile
部分中调整是否要调试符号debug
。
当您第一次查看堆栈跟踪时,您可能会对所看到的所有奇怪的函数名感到困惑。不用担心,这很正常!你有兴趣在什么的一部分,你的代码引发恐慌,但堆栈跟踪显示的所有功能在某种程度上参与。在您的示例中,您可以忽略前9个条目:这些只是处理紧急情况并生成您所看到的确切消息的函数。
条目10仍然不是您的代码,但可能也很有趣:使用您在使用运算符时会在index()
函数中触发恐慌。最后,条目11显示了您定义的功能。但是您可能已经注意到,该条目缺少文件位置...上一节介绍了解决方法。Vec<T>
[]
std
和core
堆栈跟踪的顶部。camelCase
函数和方法名称snake_case
以遵循社区范围的样式指南。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句