调试优化的 C/C++ 的有效方法有哪些?程序?

发布于 2024-08-04 11:03:19 字数 288 浏览 4 评论 0原文

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

我使用以下命令:

  • 由于使用 ddd,您看不到代码,因此我使用 gdb+ dissambler 命令并查看生成的代码;我无法真正使用它单步执行程序。
  • ndisasm

谢谢

Many times I work with optimized code (sometimes even involving vectorized loops), which contain bugs and such. How would one debug such code? I'm looking for any kind of tools or techniques. I use the following (possibly outdated) tools, so I'm looking to upgrade.

I use the following:

  • Since with ddd, you cannot see the code, I use gdb+ dissambler command and see the produced code; I can't really step through the program using this.
  • ndisasm

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风苍溪 2024-08-11 11:03:19

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

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

It is always harder to debug optimised programs, but there are always ways. Some additional tips:

  • Make a debug build, and see if you get the same bug in a debug build. No point debugging an optimised version if you don't have to.
  • Use valgrind if on a platform that supports it. The errors you see may be harder to understand, but catching the problem early often simplifies debugging.
  • printf debugging is primitive, but sometimes it is the simplest way if you have a complex issue that only shows up in optimised builds.
  • If you suspect a timing issue (especially in a multithreaded program), roll your own version of assert which aborts or prints if the condition is violated, and use it in a few select places, to rule out possible problems.
  • See if you can reproduce the problem without using -fomit-frame-pointers, since that makes code very hard to debug, and with -O2 or -O3 enabled. That might give you enough information to find the cause of your problem.
  • Isolate parts of your code, build a test-suite, and see if you can identify any testcases which fail. It is much easier to debug one function than the whole program.
  • Try turning off optimisations one by one with the -fno-X options. This might help you find common problems like strict aliasing problems.
  • Turn on more compiler warnings. Some things, like strict aliasing problems, can generate compiler warnings if they create a difference in behaviour between different optimisation levels.
迷荒 2024-08-11 11:03:19

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

When debugging release builds you can put in __asm nops; as a placeholder for breakpoints (int 3). This is nice as you can guarantee breakpoint locations without messing up compiler optimizations or writing printf/cout statements.

静赏你的温柔 2024-08-11 11:03:19

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

It's always easier to debug a non-optimized version, of course. Failing that, disassembly of the code can be helpful. Other techinques I've used include partially de-optimizing the code by forcing intermediate results to be printed or logged, or changing a critical variable to "volatile" so I can at least look at that value in the debugger.

郁金香雨 2024-08-11 11:03:19

很可能您所说的优化代码被打乱以减少周期(这使得调试变得困难),但实际上并不是非常优化。 这是我的意思的一个例子。

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

Chances are what you call optimized code is scrambled to shave cycles (which makes debugging hard) but is not really very optimized. Here is an example of what I mean.

I would turn off the compiler optimization, debug and tune it yourself, and then turn compiler optimization back on if the code has hotspots that are actually in code the compiler sees (not in outside libraries). (I define a hotspot as a part of code where the PC is often found. That automatically exempts loops containing function calls because they steal away the PC.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文