【问题标题】:How to debug a variable that is optimized away in Release build如何调试在发布版本中优化的变量
【发布时间】:2013-06-26 14:35:00
【问题描述】:

我正在使用 VS2010。我的调试版本运行良好,但我的发布版本一直在崩溃。因此,在发布版本模式下,我右键单击项目选择调试,然后选择启动新实例。在这一点上,我看到了一个我已经声明为这样的数组

int ma[4]= { 1,2,8,4};

永远不会被初始化。关于可能发生的事情的任何建议。

【问题讨论】:

  • 如何检查数组未初始化?
  • 通过在其后放置一个断点。我注意到数组中没有值。我也尝试过类似int a = ma[0]; 的操作,但没有显示任何值。
  • 请在下面阅读我的回答。您不应信任在调试发布版本时显示的值。添加一个打印语句来检查数组的值是否设置正确,我打赌你会看到它们。
  • @IvayloStrandjev 但是当然,添加打印可能会使他的程序再次运行。变量的额外使用将改变优化器处理它的方式。 (根据他使用ma 的方式,优化器可能会完全消除它。)
  • @JamesKanze 很抱歉,我不明白您的评论是什么意思

标签: c++ visual-studio-2010


【解决方案1】:

当您在 Release 中构建时,编译器会对您的代码执行许多优化。许多优化包括在可能且正确的情况下用硬编码值替换变量。例如,如果你有类似的东西:

int n = 42;
cout << "The answer is: " << n;

当优化器完成它时,它通常看起来更像:

cout << "The answer is: " <<  42;

...并且变量n 已从您的程序中完全消除。如果您正在逐步执行该程序的发布版本并尝试检查 n 的值,您可能会看到非常奇怪的值,或者调试器可能会报告 n 根本不存在。

还有许多其他优化可以应用,这使得调试优化的程序变得相当困难。在数组初始化之后放置断点可能会产生非常误导的信息,如果数组被删除,或者如果它的初始化被移动到其他地方。

另一个常见的优化是消除未使用的变量,例如:

int a = ma[0];

如果您的程序中没有实际使用a 的代码,编译器会发现a 是不需要的,并对其进行优化以使其不再存在。

为了查看 ma 已初始化的值,最简单且可靠的方法是使用所谓的 sprintf 调试:

cout << "ma values: ";
copy (ma, ma+4, ostream_iterator <int> (cout, ", "));

看看到底有什么。

【讨论】:

    【解决方案2】:

    如果您调试发布版本,调试器将报告虚假值或无法显示大多数变量的任何值。检查变量值是否在 Release 构建中的最安全方法是使用日志记录。

    所以很可能您的数组在 Release 中已初始化,就像在 Debug 构建中一样,但您无法通过调试器看到这一点。看来您还有其他问题导致代码在 Release 中崩溃。查找其他一些未初始化的变量或一些堆栈损坏/索引越界访问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 2010-10-27
      • 2020-08-02
      • 1970-01-01
      • 2011-05-28
      相关资源
      最近更新 更多