cjk Asked: 2025-03-06 18:57:24 +0800 CST2025-03-06 18:57:24 +0800 CST 2025-03-06 18:57:24 +0800 CST 为什么在 VSCode/LLDB 中调试 Rust 时调试器中的局部变量显示会消失? 772 我正在使用 LLDB 在 VSCode 中调试 Rust。为什么当我在图像代码的范围末尾放置断点时,调试器中出现的一些局部变量会消失?是否有设置可以防止它们消失? 前 后 在范围末尾放置一个断点来检查局部变量的值是检查该值的最简单方法,因此如果可能的话,我们不想使用耗时的 println 调试方法。 visual-studio-code 1 个回答 Voted Best Answer Jim Ingham 2025-03-07T05:13:21+08:002025-03-07T05:13:21+08:00 变量的调试信息由程序中该变量可见的一系列 pc 范围以及每个范围内变量在内存或寄存器中的位置组成。在这些范围之外,变量的值是未知的。这是由编译器做出的决定,调试器只是向您显示它在调试信息中写的内容。 请注意,调试信息能够表达变量在某个 PC 范围的寄存器中,然后移动到另一个范围的堆栈中,然后再返回到寄存器等。因此,如果编译器正确地发出调试信息,调试器就可以跟踪类似的移动。 我不知道为什么 Rust 编译器认为在该函数结束时“a”仍在范围内而“b”不在。但是,大多数语言都不能保证变量的存储在变量定义的整个语义范围内保留,而使用 ARC 或其他技术管理对象生命周期的语言通常喜欢在引用变量的最后一段代码之后删除变量,因为这样可以提高内存效率。所以一般来说,你只能保证在最后一次使用之前查看变量。 大多数 C 编译器在 -O0 下运行时不会以这种方式重用变量的堆栈空间。但例如在 swift 中,编译器添加了一个“影子变量”,该变量仅在优化器关闭且生成调试信息时发出,用于人为延长变量的寿命以匹配其范围,以帮助调试。这是解决 swift 变量回收急切问题的最干净的方法。也许 Rust 需要这样的东西? 无论如何,TL;DR 是 Rust 编译器必须修复的问题。编译器告诉我们它不知道b当前 PC 在哪里,调试器永远不应该尝试猜测值,否则弊大于利。
变量的调试信息由程序中该变量可见的一系列 pc 范围以及每个范围内变量在内存或寄存器中的位置组成。在这些范围之外,变量的值是未知的。这是由编译器做出的决定,调试器只是向您显示它在调试信息中写的内容。
请注意,调试信息能够表达变量在某个 PC 范围的寄存器中,然后移动到另一个范围的堆栈中,然后再返回到寄存器等。因此,如果编译器正确地发出调试信息,调试器就可以跟踪类似的移动。
我不知道为什么 Rust 编译器认为在该函数结束时“a”仍在范围内而“b”不在。但是,大多数语言都不能保证变量的存储在变量定义的整个语义范围内保留,而使用 ARC 或其他技术管理对象生命周期的语言通常喜欢在引用变量的最后一段代码之后删除变量,因为这样可以提高内存效率。所以一般来说,你只能保证在最后一次使用之前查看变量。
大多数 C 编译器在 -O0 下运行时不会以这种方式重用变量的堆栈空间。但例如在 swift 中,编译器添加了一个“影子变量”,该变量仅在优化器关闭且生成调试信息时发出,用于人为延长变量的寿命以匹配其范围,以帮助调试。这是解决 swift 变量回收急切问题的最干净的方法。也许 Rust 需要这样的东西?
无论如何,TL;DR 是 Rust 编译器必须修复的问题。编译器告诉我们它不知道
b
当前 PC 在哪里,调试器永远不应该尝试猜测值,否则弊大于利。