GDB:我们如何从std :: tuple中提取值

Fin*_*ers 5 c++ gdb c++11

我们如何在std :: tuple中提取/打印单个值?

以下是名为test.cc的文件中的示例程序.

#include <tuple>
#include <iostream>

 using namespace std;

 int main() {
     auto t = make_tuple(111, 222);
     cout << std::get<0>(t) << endl
          << std::get<1>(t) << endl;
     return 0;
 }
Run Code Online (Sandbox Code Playgroud)

编译它

g++ --std=c++11 -g test.cc
Run Code Online (Sandbox Code Playgroud)

在gdb中运行它

gdb --args ./a.out
...
(gdb) start
Temporary breakpoint 1 at 0x400836: file test.cc, line 7.
Starting program: /home/fmlheureux/a.out

Temporary breakpoint 1, main () at test.cc:7
7           auto t = make_tuple(111, 222);
(gdb) n
9                << std::get<1>(t) << endl;
(gdb) p t
$1 = std::tuple containing = {[1] = 111, [2] = 222}
Run Code Online (Sandbox Code Playgroud)

最后一个命令将元组打印为整体.如何提取单个值?我天真的尝试失败了.

(gdb) p get<0>(t)
No symbol "get<0>" in current context.
(gdb) p std::get<0>(t)
No symbol "get<0>" in namespace "std".
Run Code Online (Sandbox Code Playgroud)

Tom*_*mey 7

不幸的是,gdb中的漂亮打印代码是一个仅显示功能 - 因此虽然它有助于以一种很好的方式显示元组,但它不允许您进一步访问它.

正常的问题t.get<0>是这些微小的访问器方法通常被编译器完全优化 - 所以没有副本可以调用.而且,虽然gdb有一个"xmethod"功能,可用于提供这些访问器的gdb端Python实现,但info xmethods至少对我来说,还没有人为此做过这样的事情std::tuple.

那么你只剩下一个选项:检查实现.所以,首先打印原始元组:

(gdb) p/r t
$3 = {<std::_Tuple_impl<0ul, int, int>> = {<std::_Tuple_impl<1ul, int>> = {<std::_Head_base<1ul, int, false>> = {
        _M_head_impl = 222}, <No data fields>}, <std::_Head_base<0ul, int, false>> = {_M_head_impl = 111}, <No data fields>}, <No data fields>}
Run Code Online (Sandbox Code Playgroud)

在这里,您可以看到元组的"真实"结构,并直接访问字段:

(gdb) print ((std::_Head_base<1ul, int, false>) t)._M_head_impl
$7 = 222
Run Code Online (Sandbox Code Playgroud)

这种中间类型是一种痛苦,呃?需要让gdb选择正确的_M_head_impl字段.如果这是你计划做很多事情的话,我建议写一下xmethod.或者您也可以轻松编写Python便捷功能来自动访问; 这种内省对Python API来说有点简单.

  • 感谢您的解决方案!对于未来的读者,我想指出“1ul”是元组中的索引。 (2认同)