【问题标题】:What are efficient ways to debug an optimized C/C++ program?调试优化的 C/C++ 程序的有效方法是什么?
【发布时间】:2009-09-07 02:37:37
【问题描述】:

很多时候我使用优化的代码(有时甚至涉及矢量化循环),其中包含错误等。如何调试这样的代码?我正在寻找任何类型的工具或技术。我使用以下(可能已过时)工具,因此我正在寻求升级。

我使用以下内容:

  • 由于用ddd,看不到代码,我用gdb+ dissambler命令看生成的代码;我无法真正使用它来逐步完成程序。
  • ndisasm

谢谢

【问题讨论】:

  • 不是很有见地,但 MSDN 有一篇关于调试优化代码的文章(至少在 Windows 世界中):msdn.microsoft.com/en-us/library/606cbtzs.aspx
  • 我不知道我们的代码是否是多平台的,但是使用 Visual Studio,您可以调试编译器优化的程序以及调试版本。单步执行代码、刹车点、监视窗口等。
  • @StefanWoe:是的,您可以调试经过优化的 MS VC++ 程序,但您会遇到相同的基本问题。源代码和汇编代码往往不够合理,无法理解。所以,通常断点真的设置在其他地方,监视窗口给你废话等等。

标签: c++ c debugging disassembly


【解决方案1】:

调试优化程序总是很困难,但总有办法。一些额外的提示:

  • 进行调试构建,看看您是否在调试构建中遇到相同的错误。如果非必要,调试优化版本是没有意义的。
  • 如果在支持它的平台上使用 valgrind。您看到的错误可能更难理解,但及早发现问题通常会简化调试。
  • printf 调试是原始的,但如果您遇到仅在优化构建中出现的复杂问题,有时它是最简单的方法。
  • 如果您怀疑存在时序问题(尤其是在多线程程序中),请滚动您自己的 assert 版本,如果违反条件则会中止或打印,并在几个选定的地方使用它,以排除可能的问题。李>
  • 看看你是否可以在不使用 -fomit-frame-pointers 的情况下重现问题,因为这使得代码很难调试,并且启用了 -O2 或 -O3。这可能会为您提供足够的信息来找出问题的原因。
  • 隔离部分代码,构建测试套件,然后查看是否可以识别任何失败的测试用例。调试一个函数比调试整个程序要容易得多。
  • 尝试使用 -fno-X 选项逐一关闭优化。这可能会帮助您找到常见问题,例如严格的别名问题。
  • 开启更多编译器警告。如果某些问题(例如严格的别名问题)在不同优化级别之间造成行为差异,则可能会生成编译器警告。

【讨论】:

  • printf 调试的缺陷是它可以掩盖优化错误,因为将数据传递给 printf 调用的代码会阻止代码执行相同的优化。 (而且我遇到过很多调试代码可以正常工作并且经过优化的实例并不是优化器错误。OTOH,printf 将帮助您找到优化器错误,并且是您需要深入了解程序集以确定您是否有的线索一个优化器错误。
  • +1 用于建议调试构建和 valgrind - 假设您没有偶然发现编译器错误,那么当调试构建不会时优化构建失败的唯一原因是您重新踩在内存的不同(更重要)部分
【解决方案2】:

在调试发布版本时,您可以放入 __asm nops;作为断点的占位符(int 3)。这很好,因为您可以保证断点位置而不会弄乱编译器优化或编写 printf/cout 语句。

【讨论】:

【解决方案3】:

当然,调试非优化版本总是更容易。如果做不到这一点,反汇编代码可能会有所帮助。我使用的其他技术包括通过强制打印或记录中间结果来部分反优化代码,或者将关键变量更改为“volatile”,这样我至少可以查看 that 中的值调试器。

【讨论】:

    【解决方案4】:

    很有可能你所说的优化代码被加扰以减少周期(这使得调试变得困难),但实际上并不是非常优化。 Here is an example of what I mean.

    我会关闭编译器优化,自己调试和调整它,然后如果代码的热点实际上在编译器看到的代码中(而不是在外部库中),则重新打开编译器优化。 (我将热点定义为经常发现 PC 的代码的一部分。它会自动排除包含函数调用的循环,因为它们会偷走 PC。)

    【讨论】:

      猜你喜欢
      • 2010-09-09
      • 1970-01-01
      • 2012-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多