使用gdb调试c ++模板

Wil*_*ill 6 c++ gdb

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

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

    我试过了p T.它说gdb不能打印一种类型.

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

    让我们说功能foo<T>(...)有两种可能的形式,foo<int>(...)和foo<long>(...).如何设置一个断点,以便gdb只在第一个使用的断点上暂停int,而不是第二个使用long?

编辑:如果可以通过行号设置断点,那将是很好的.这有很多很好的理由,例如.函数的初始部分可能需要很长时间才能运行,我希望调试的地方可能在if声明等内部.

Tom*_*mey 5

您可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

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

(gdb) ptype T
type = const char *
Run Code Online (Sandbox Code Playgroud)

查看当前帧:

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

我可以使用那里给出的函数名称设置断点:

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


Kla*_*aus 5

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

gdb> rbreak Foo<.*>
Run Code Online (Sandbox Code Playgroud)

仅在已知实例上设置断点

gdb> break Foo<int>
Run Code Online (Sandbox Code Playgroud)

您也可以使用,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;
}
Run Code Online (Sandbox Code Playgroud)

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

g++ main.cpp -g -o go
Run Code Online (Sandbox Code Playgroud)

运行gdb:

gdb go
Run Code Online (Sandbox Code Playgroud)

并测试:

gdb> rbreak Foo<int>
gdb> run
gdb> backtrace
gdb> cont
Run Code Online (Sandbox Code Playgroud)

如您所见:仅模板的一个实例受到影响。

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

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

如您所见,它在Foo<int>这里。