C ++ gdb:如何在向量中以及在该范围内显示元素成员的子集?

时间:2017-06-26 07:24:12

标签: c++ debugging stl gdb codelite

此答案基于bcummingHow 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

0 个答案:

没有答案