c++ - 如何在GDB中解释backtrace的模板函数签名?

标签 c++ c++11 templates gdb

GDB的backtrace输出非常困惑,尤其是对于模板。

例如:

Thread 2 (LWP 100146 of process 1245):
#0  thr_new () at thr_new.S:3
#1  0x000000080025c3da in _pthread_create (thread=0x7fffdfffd880, attr=<optimized out>, start_routine=0x205500 <void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (std::__1::__async_assoc_state<void, std::__1::__async_func<func2(std::__1::atomic<long>&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<func2(std::__1::atomic<long>&)::$_0> >*> >(void*)>, arg=0x8007fa8e0) at /usr/src/lib/libthr/thread/thr_create.c:188
#2  0x0000000000204e40 in std::__1::thread::thread<void (std::__1::__async_assoc_state<void, std::__1::__async_func<func2(std::__1::atomic<long>&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<func2(std::__1::atomic<long>&)::$_0> >*, void>(void (std::__1::__async_assoc_state<void, std::__1::__async_func<func2(std::__1::atomic<long>&)::$_0> >::*&&)(), std::__1::__async_assoc_state<void, std::__1::__async_func<func2(std::__1::atomic<long>&)::$_0> >*&&) ()
#3  0x0000000000204309 in std::__1::future<void> std::__1::__make_async_assoc_state<void, std::__1::__async_func<func2(std::__1::atomic<long>&)::$_0> >(std::__1::__async_func<func2(std::__1::atomic<long>&)::$_0>&&) ()
#4  0x00000000002035ea in std::__1::future<std::__1::__invoke_of<std::__1::decay<func2(std::__1::atomic<long>&)::$_0>::type>::type> std::__1::async<func2(std::__1::atomic<long>&)::$_0>(std::__1::launch, func2(std::__1::atomic<long>&)::$_0&&) ()
#5  0x0000000000203462 in func2(std::__1::atomic<long>&) ()
#6  0x0000000000206f18 in main::$_1::operator()() const ()
#7  0x0000000000206eed in void std::__1::__async_func<main::$_1>::__execute<>(std::__1::__tuple_indices<>) ()
#8  0x0000000000206ea5 in std::__1::__async_func<main::$_1>::operator()() ()
#9  0x0000000000206df3 in std::__1::__async_assoc_state<void, std::__1::__async_func<main::$_1> >::__execute() ()
#10 0x0000000000207183 in void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (std::__1::__async_assoc_state<void, std::__1::__async_func<main::$_1> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<main::$_1> >*> >(void*) ()
#11 0x000000080025c776 in thread_start (curthread=0x8007de500) at /usr/src/lib/libthr/thread/thr_create.c:292
#12 0x0000000000000000 in ?? ()
Backtrace stopped: Cannot access memory at address 0x7fffdfffe000

在第8帧中,有三对括号,std::__1::__async_func<main::$_1>::operator()() ()到底是什么意思?

最佳答案

第8帧没有调试信息,因此GDB无法准确描述它。

考虑以下测试案例:

struct Foo {
  int operator()(void) {
    return 1;  // line 3
  }
};

int main()
{
  return Foo()();
}


当使用g++ -g t.cc编译并在第3行的断点处编译时,GDB将显示以下内容:
Breakpoint 1, Foo::operator() (this=0x7fffffffdcff) at t.cc:3
3       return 1;
(gdb) bt 
#0  Foo::operator() (this=0x7fffffffdcff) at t.cc:3
#1  0x0000555555555139 in main () at t.cc:10

但是编译没有-g的相同源代码,在_ZN3FooclEv上设置一个断点,这将是您看到的:
Breakpoint 1, 0x0000555555555140 in Foo::operator()() ()
(gdb) bt 
#0  0x0000555555555140 in Foo::operator()() ()
#1  0x0000555555555139 in main ()

前两套括号来自对符号的去拼:
c++filt _ZN3FooclEv
Foo::operator()()

第三组是由GDB添加的,因为要显示的符号在.text节中,并被假定为函数。

关于c++ - 如何在GDB中解释backtrace的模板函数签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59943099/

相关文章:

c++ - 长整数输出错误

C++ 迭代器如何实现 next() 和 previous() 函数

c++ - 继承的运算符重载不适用于派生类

c++ - 什么先来 - 模板实例化与宏扩展?

c++ - 如何将文件中的数据读取到结构中?

c++ - 为什么这段代码在赋值运算符之后调用了拷贝构造函数?

c++ - 转发初始化列表表达式

c++ - 如何在没有 sizeof 的情况下最好地防止自定义断言中出现未使用的变量警告?

c++ - 处理特定类型元素的任何容器的非模板函数

c++ - 这个 C++ 指针容器安全吗?