如何解释GDB中回溯的模板函数签名?

How to interpret the template function signature of backtrace in GDB?

本文关键字:函数 回溯 何解释 解释 GDB      更新时间:2023-10-16

GDB的回溯输出非常混乱,尤其是对于模板。

例如:

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部分中,并假定为函数。