【问题标题】:How do I print the elements of a C++ vector in GDB?如何在 GDB 中打印 C++ 向量的元素?
【发布时间】:2010-09-20 04:00:13
【问题描述】:

我想在 GDB 中检查 std::vector 的内容,我该怎么做?为简单起见,假设它是std::vector<int>

【问题讨论】:

标签: c++ debugging stl vector gdb


【解决方案1】:

使用 GCC 4.1.2,要打印名为 myVector 的整个 std::vector,请执行以下操作:

print *(myVector._M_impl._M_start)@myVector.size()

要仅打印前 N 个元素,请执行以下操作:

print *(myVector._M_impl._M_start)@N

说明

这可能很大程度上取决于您的编译器版本,但对于 GCC 4.1.2,指向内部数组的指针是:

myVector._M_impl._M_start 

从指针 P 开始打印数组的 N 个元素的 GDB 命令是:

print P@N

或者,以简短的形式(对于标准 .gdbinit):

p P@N

【讨论】:

  • 呵呵,这件事之前一直困扰着我,所以我今天早上才查了一下,并把它作为备忘录添加给自己(正如 Jeff 本人推荐的那样)。
  • 另外,如果你只想要一个特定的向量元素,myVector._M_impl._M_start + n(对于第 n 个元素)
  • 不适合我。 Cannot evaluate function -- may be inlined
  • 打印单个元素,例如第二个元素:print (myVector._M_impl._M_start)[2]
  • 要在 GDB 7.0+ 下查找编译器的特殊名称(_M_impl 等),请使用 print /r myVector
【解决方案2】:

要查看矢量 std::vector myVector 内容,只需输入 GDB:

(gdb) print myVector

这将产生类似于:

$1 = std::vector of length 3, capacity 4 = {10, 20, 30}

要实现上述目标,您需要 gdb 7(我在 gdb 7.01 上测试过)和一些 python 漂亮的打印机。这些的安装过程在gdb wiki有描述。

更重要的是,在上面安装之后,它可以很好地与 Eclipse C++ 调试器 GUI(以及任何其他使用 GDB 的 IDE,我认为)。

【讨论】:

  • 只要向量元素是可直接解释的,它就可以正常工作。但如果向量包含指向感兴趣项目的指针,则无济于事。
  • 坦率地说,我不觉得gdb wiki 页面特别可读,可能是因为它现在“稍微”过时了?例如,我的印象是$HOME/.gdbinit 的建议内容是必要的。目前我根本没有这样的文件,gdb 正确显示了std::vector 的内容。但是,由于在我的“漫无目的”尝试中,我刚刚安装然后卸载了cgdb,并且我已经安装了libstdc++5,所以我不知道为什么漂亮的打印不起作用,而现在它可以工作了。
【解决方案3】:

将以下内容放入 ~/.gdbinit

define print_vector
    if $argc == 2
        set $elem = $arg0.size()
        if $arg1 >= $arg0.size()
            printf "Error, %s.size() = %d, printing last element:\n", "$arg0", $arg0.size()
            set $elem = $arg1 -1
        end
        print *($arg0._M_impl._M_start + $elem)@1
    else
        print *($arg0._M_impl._M_start)@$arg0.size()
    end
end

document print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display
end

重启 gdb(或获取 ~/.gdbinit)后,像这样显示相关帮助

gdb) help print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display

示例用法:

(gdb) print_vector videoconfig_.entries 0
$32 = {{subChannelId = 177 '\261', sourceId = 0 '\000', hasH264PayloadInfo = false, bitrate = 0,     payloadType = 68 'D', maxFs = 0, maxMbps = 0, maxFps = 134, encoder = 0 '\000', temporalLayers = 0 '\000'}}

【讨论】:

  • 感谢您的代码!我想有一个错字,“print *($arg0._M_impl._M_start + $elem)@1”应该是“print *($arg0._M_impl._M_start + $arg1)@1”?我使用以下修改:定义 print_vector if $argc == 2 if $arg1 >= $arg0.size()-1 printf "Error, %s.size() = %d, printing last element:\n", " $arg0", $arg0.size()-1 end print *($arg0._M_impl._M_start + $arg1)@1 else print *($arg0._M_impl._M_start)@$arg0.size() end end跨度>
  • el magnifico!摩卡格拉西亚斯
【解决方案4】:

在调试时“观察”STL 容器有点问题。以下是我过去使用过的 3 种不同的解决方案,它们都不是完美的。

1) 使用来自http://clith.com/gdb_stl_utils/ 的 GDB 脚本 这些脚本允许您打印几乎所有 STL 容器的内容。问题是这不适用于嵌套容器,如一堆集合。

2) Visual Studio 2005 对观看 STL 容器提供了极好的支持。这适用于嵌套容器,但这仅适用于它们的 STL 实现,并且如果您将 STL 容器放入 Boost 容器中则不起作用。

3) 在调试时为要打印的特定项目编写自己的“打印”函数(或方法),并在 GDB 中使用“调用”来打印项目。请注意,如果您的打印函数没有在代码中的任何地方调用,g++ 将执行死代码消除,并且 GDB 将找不到“打印”函数(您将收到一条消息,指出该函数已内联)。所以用 -fkeep-inline-functions 编译

【讨论】:

    【解决方案5】:

    聚会有点晚了,所以下次我做这个搜索时主要是提醒我!

    我已经可以使用了:

    p/x *(&vec[2])@4
    

    vec 打印4 个元素(十六进制),从vec[2] 开始。

    【讨论】:

      猜你喜欢
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      • 2021-12-30
      相关资源
      最近更新 更多