此答案基于bcumming中How do I print the elements of a C++ vector in GDB?的评论,并在64位Debian 8上使用Codelite 10.0.0,gcc 4.9.2和gdb 7.7.1进行了测试。该问题涉及显示矢量的所有元素。 John Carter的答案有一个缺点,即涉及内部库依赖的指针名称,以及即使下级(正在调试的程序)没有编译运算符[]的代码也能正常工作的优点。 (见:gdb Could not find operator[]。)
如果我想从索引4
开始看到向量vecV
p的[3]
个元素,那么gdb print命令是:
p *(&vecV[3]) @ 4
这是我的答案。多年来我一直试图弄清楚如何做到这一点,据我所知,它并不在gdb手册中。以下文字涉及该技术的变化和原理。
这样做的一个原因是减少显示向量的所有元素的混乱。另一种方法是减少gdb响应Watch窗口行所需的时间,例如每次“跳过”IDE操作。我发现gdb,基于Python的STL漂亮的打印机制,可能需要几秒或几十秒来响应大量的简单元素,或者几个更复杂的元素。
这是gdb手册第10.4节Artificial Arrays中描述的技术向量的应用程序,其中二元运算符@
适用于C风格的数组:p arrA[3] @ 4
但不是向量和比如容器库(STL)。
上面使用@
,从特定的向量元素开始,在Codelite的Watch窗口中工作正常,其中不需要上面的p
部分。 Codelite显示的单行可以通过单击向右箭头来打开,以显示元素和对象的所有值,它们包含的字符串向量等。但是,它不能作为仅显示每个向量元素范围的一个内部元素(例如某个类对象,int或字符串)的基础。为此,必须创建四个Watch行(添加p
以直接驱动gdb):
vec[3].log
vec[4].log
vec[5].log
vec[6].log
这当然是乏味的。解决方案是向下级添加一些变量,这些变量仅供gdb使用。这些可以是静态的,在任何函数之外,因此“全局”:
static int XX = 0;
static int YY = 0;
static int ZZ = 0;
可以在Codelite中设置它们的值,而在断点处暂停下级,通过输入到gdb控制台底部的“发送”栏中的set XX = 3
等命令,该命令位于“ (红色瓢虫图标)“调试器”窗口的“输出”选项卡。这使我可以使用四条Watch线,每条线只关注矢量中四个所选元素的“log”成员,通过改变XX
的值,可以很容易地将其引导到矢量的任何部分。 / p>
vecV[XX + 0].log
vecV[XX + 1].log
vecV[XX + 2].log
vecV[XX + 3].log
更重要的是,根据我的经验,更改XX
会导致Codelite不仅显示新数据,还会以红色突出显示与之前显示的XX
值不同的数据。
如果log
是一个包含字符串的对象,该字符串太长而无法在Watch窗口中查看(设置> GDB设置> GNU gdb调试器>常规>显示>要显示的元素数量数组/字符串),然后我可以使用上面的方案和substr()
与其他一些gdb-set变量来控制显示字符串的范围:
vecV[XX + 0].log.strS.substr(AA, BB)
vecV[XX + 1].log.strS.substr(AA, BB)
vecV[XX + 2].log.strS.substr(AA, BB)
vecV[XX + 3].log.strS.substr(AA, BB)
这些变量可以应用于主要技术,通过向gdb控制台输入一个或两个命令,而不是编辑Watch窗口行,通常涉及大量的操作,从而为向量提供可操纵,可调整大小的显示窗口。鼠标/轨迹球单击以重新打开感兴趣的对象的所有分支:
(&vecV[YY]) @ ZZ