ddd 调试器使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ddd 调试器使用相关的知识,希望对你有一定的参考价值。

参考技术A 原始的ddd字体丑陋,像素化,需要设置合适的字体大小,点击Edit->Preferences->Fonts。然后看到不同设置。然后点击Browse,显示如下:

点击图中的fmly,选择fixed(这是系统提示作者选fixed的,本人ubuntu系统,不同系统可能不同),然后点击ptSz,选择字体大小,我选的200,然后点击select保存即可。其他Browse都是类似设置。最后点击OK保存即可。

行号是十分重要的信息,在调试时十分有用,可是默认没有显示,需要自己设置。点击Edit->Preferences->Source,然后选中Display Source Line Numbers即可。

ddd是一个借助与gdb的强大的图形化debug工具。它可以使得gdb是可视化的,不再是枯燥的命令行的形式。而且它支持数据的显示,包括列表和图的形式等。特别是图的形式,在进行debug时特别直观而有用。

由于ddd使用gnuplot画图,所以确认系统上安装了gnuplot,未安装的话则sudo apt-get install gnuplot即可。打开Edit->Preferences->Helpers可以看到Plot设置的选项,Plot Window选项为External或者Builtin。我选择的是External,不知道为何,选中Builtin时在画图时一直是显示Starting gnuplot的状态。这样就设置好了gnuplot。

以作者调试的cuda程序为例。在进入kernel核函数后,有一个共享内存数组dest_data长度64,则可在如下输入"dest_data[0]@64",然后点击右边的plot,则可以显示dest_data的值

这是对数据排序的程序,当程序运行到如下位置时,数据还未被赋予值:

运行到如下位置时,数据已经排序好:

调试优化的 C/C++ 程序的有效方法是啥?

【中文标题】调试优化的 C/C++ 程序的有效方法是啥?【英文标题】: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++ 程序,但您会遇到相同的基本问题。源代码和汇编代码往往不够合理,无法理解。所以,通常断点真的设置在其他地方,监视窗口给你废话等等。 【参考方案1】:

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

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

【讨论】:

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

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

【讨论】:

我不了解 GCC,但是在 MSVC 中有一个内联汇编块会影响优化:“在函数中包含汇编语言会影响其他一些函数范围的优化” - msdn.microsoft.com/en-us/library/5hd5ywk0.aspx【参考方案3】:

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

【讨论】:

【参考方案4】:

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

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

【讨论】:

以上是关于ddd 调试器使用的主要内容,如果未能解决你的问题,请参考以下文章

linux 下面怎么用gdb调试多个.c文件?

从附加到 ddd/dbx 的崩溃进程生成核心转储

在 perl 中调试由 SWIG 包装的共享库

如何在 ddd (gdb) 中跳过过去的循环

调试用 yasm 创建的汇编代码

numpy C语言源代码调试