用gdb调试c++模板

debug c++ template with gdb

本文关键字:模板 c++ 调试 gdb      更新时间:2023-10-16

当我使用模板在函数内部调试时,

  1. 如何知道当前函数使用的模板类型?

    我试过p T。它说gdb不能打印一个类型。

  2. 如何破解特定的模板类型?

    假设函数foo<T>(...)有两种可能的形式,foo<int>(...)foo<long>(...)。如何设置断点,使gdb只暂停在第一个使用int的断点上,而不暂停在第二个使用long的断点上?

编辑:如果可以通过行号设置断点,那就太好了。这有很多很好的原因,例如,函数的初始部分可能需要很长时间才能运行,我希望调试的地方可能在if语句内部等。

要为所有实例设置断点,请使用:

gdb> rbreak Foo<.*>

只在已知实例上设置断点

gdb> break Foo<int>

您也可以使用rbreak Foo<int>,但使用一个计算正则表达式的调用是没有意义的,但您没有给出:-)

示例代码:

#include <iostream>
#include <string>
template < typename T>
T Foo(T t) { return t; }
int main()
{
    std::cout << Foo<int>(1) << std::endl;
    std::cout << Foo<std::string>("Hallo") << std::endl;
}

只需使用调试信息进行编译:

g++ main.cpp -g -o go

运行gdb:

gdb go

测试:

gdb> rbreak Foo<int>
gdb> run
gdb> backtrace
gdb> cont

正如您所看到的:只有一个模板实例受到影响。

在回溯中,您可以看到哪个模板实例被调用:

#0  Foo<int> (t=1) at main.cpp:5
#1  0x0000000000400b69 in main () at main.cpp:9

正如你所看到的,这里是Foo<int>

要回答评论:"有没有办法在某一行的特定已知实例中放置断点"

是的!

gdb> break main:692
gdb> info break

这将返回类似的东西

Num     Type           Disp Enb Address            What
5       breakpoint     keep y   <MULTIPLE>         
5.1                         y   0x00000000004026db in Foo<int>(int) at main.cpp:692
5.2                         y   0x00000000004027a6 in Foo<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) at main.cpp:692
(gdb)

现在你可以禁用特定的实例:

gdb> disable 5.2

您不能删除特定的";子断点";。但禁用正是你所需要的。如果你喜欢,你也可以提供一系列实例,例如:

gdb> disable 5.1-2

您可以使用ptype而不是p来打印类型。有了一个足够新的(几年前)g++和gdb,这将起作用。

考虑这个来源:

#include <iostream>
template<typename T>
struct S
{
  S(T t)
  {
    std::cout << t;
  }
};
int main()
{
  S<const char*> s2("hello");
  S<int> s1(23);
  return 0;
}

在这里,我可以进入s2的构造函数,并查看T:

(gdb) ptype T
type = const char *

看看当前帧:

(gdb) frame
#0  S<char const*>::S (this=0x7fffffffe35f, t=0x400940 "hello") at q.cc:8
8       std::cout << t;

我可以使用给定的函数名设置断点:

(gdb) b S<const char *>::S
Breakpoint 2 at 0x40087a: file q.cc, line 8.