在gdb中检查模板参数包

7

我正在尝试调试以下简单程序:

#include <iostream>

template <class... Args>
void printAll(Args&&... args) {
    using swallow = int[];
    swallow{0,
        (std::cout << args, 0)...
    };  
}

int main() {
    printAll(1, "23", 4); 
}

使用gcc 4.9.2编译:

g++ -std=c++11 -g -O0 foo.cxx

然后使用gdb 7.9进行调试:

gdb a.out

(gdb) break foo.cxx:5
Breakpoint 1 at 0x400884: file foo.cxx, line 5.
(gdb) run
Starting program: /..[snip]../a.out 

Breakpoint 1, printAll<int, char const (&) [3], int>(int&&, char const (&) [3], int&&) () at foo.cxx:6
6       swallow{0,
(gdb) bt
#0  printAll<int, char const (&) [3], int>(int&&, char const (&) [3], int&&) () at foo.cxx:6
#1  0x0000000000400813 in main () at foo.cxx:12

我在正确的函数中,但是没有办法检查参数包:

(gdb) info args
No arguments.
(gdb) print args
No symbol "args" in current context.
(gdb) inspect args
No symbol "args" in current context.

我如何实际检查这些参数?

1个回答

5

相关:显示GDB中参数包的值

这里有两个问题;首先,g++使用标签DW_TAG_GNU_template_parameter_packDW_TAG_GNU_formal_parameter_pack以DWARF格式发出参数包调试信息,但gdb尚不支持(链接的PR)

即使这个问题被解决了,我们仍然遇到另一个问题,就是g++发出的调试信息是有问题的;它缺少参数名称(DW_AT_name)(链接的PR)

说实话,C++11在GDB中的支持相当糟糕(这并不奇怪,因为它实际上已经被放弃了很长时间);对于C++11的另一个接近停滞的错误是,直到版本8才支持rvalue引用(DW_TAG_rvalue_reference_type,打印出像<unknown type in /tmp/a.out, CU 0x0, DIE 0x7f>这样的错误消息。

解决方法(除了使用clang或不使用DW_TAG_GNU_template_parameter_pack标签的旧版g++(例如4.4.7)之外)是使用GCC扩展的stab调试格式

g++ -std=c++11 -gstabs+ -O0 foo.cxx
(gdb) s
void printAll<int, char const (&) [3], int>(int, int&&, char const (&) [3], int&&) (i=999, args#0=@0x7fffffffe45c: 1, args#1=..., args#2=@0x7fffffffe458: 4)
    at p.cpp:7
7       swallow{0,
(gdb) p 'args#0'
$1 = (int &) @0x7fffffffe45c: 1

可以工作!而且非常晦涩。似乎那个问题的 OP 没有从链接的答案中得到他想要的东西?我们认为应该将那个问题关闭为此问题的重复。 - Barry
已更新链接到问题跟踪器,并带有修补程序。 - ecatmur
GCC 14.0.0: g++: 警告:不再支持选项‘-gstabs+’。 - user2023370

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接