Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是什么导致我的堆栈中出现神秘的重复条目?_C++_Linux_Debugging_Gdb_G++ - Fatal编程技术网

C++ 是什么导致我的堆栈中出现神秘的重复条目?

C++ 是什么导致我的堆栈中出现神秘的重复条目?,c++,linux,debugging,gdb,g++,C++,Linux,Debugging,Gdb,G++,我正在调查一个死锁错误。我用gcore取了一个内核,发现我的一个函数似乎已经调用了自己——尽管它没有进行递归函数调用 以下是来自gdb的堆栈片段: Thread 18 (Thread 4035926944 (LWP 23449)): #0 0xffffe410 in __kernel_vsyscall () #1 0x005133de in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0 #2 0x00510017 in _L_

我正在调查一个死锁错误。我用
gcore
取了一个内核,发现我的一个函数似乎已经调用了自己——尽管它没有进行递归函数调用

以下是来自gdb的堆栈片段:

Thread 18 (Thread 4035926944 (LWP 23449)):
#0  0xffffe410 in __kernel_vsyscall ()
#1  0x005133de in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0
#2  0x00510017 in _L_mutex_lock_182 () from /lib/tls/libpthread.so.0
#3  0x080d653c in ?? ()
#4  0xf7c59480 in ?? () from LIBFOO.so
#5  0x081944c0 in ?? ()
#6  0x081944b0 in ?? ()
#7  0xf08f3b38 in ?? ()
#8  0xf7c3b34c in FOO::Service::releaseObject ()
   from LIBFOO.so
#9  0xf7c3b34c in FOO::Service::releaseObject ()
   from LIBFOO.so
#10 0xf7c36006 in FOO::RequesterImpl::releaseObject ()
   from LIBFOO.so
#11 0xf7e2afbf in BAR::BAZ::unsubscribe (this=0x80d0070, sSymbol=@0xf6ded018)
    at /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stl_tree.h:176
...more stack
我省略了一些名称:FOO和BAR是名称空间。BAZ是一个类

有趣的部分是#8和#9,调用
Service::releaseObject()
。此函数不调用自身,也不调用任何调用它的函数。。。它不是递归的。那么为什么它会在堆栈中出现两次呢

这是调试器创建的人工制品,还是真实的

您会注意到,最里面的调用正在等待互斥-我想这可能是我的死锁<代码>服务::releaseObject()锁定互斥锁,因此如果它神奇地传送回自身内部,那么死锁肯定会发生

一些背景: 这是在RHEL4上使用g++v3.4.6编译的。这是一个64位操作系统,但这是32位代码,用-m32编译。它在-O3下得到优化。我不能保证应用程序代码的编译选项与LIBFOO代码完全相同

Class
Service
没有虚拟函数,因此没有vtable。类
RequesterImpl
继承自一个完全虚拟的接口,因此它确实有一个vtable。

堆栈跟踪在x86上的任何优化级别都是不可靠的:
-O1
和更高的enable
-fomit帧指针
得到“坏”堆栈的原因是
\ull\u mutex\u lock\u wait
具有不正确的展开描述符(它是用手工编码的汇编编写的)。我相信这是最近(2008年)修复的,但找不到确切的补丁


一旦
GDB
stack放卷机“失去平衡”,就会产生伪帧(#2到#8),但最终发现了一个使用帧指针的帧,并为堆栈的其余部分生成了正确的堆栈跟踪。

那么,gdb会将丢失的帧指针解释为堆栈中的重复函数吗?是的,很可能相同函数的第二个实例实际上是一个无帧函数。这个答案不正确:for 32位代码-任何-O优化级别都不会选择fomit帧指针。不过,MSVC的调试器通常可以处理丢失的帧指针。嗯,阅读GCC源代码表明您确实是正确的:x86在所有优化级别都启用帧指针。x86_64通常会启用(所有非Mach-O)省略任何非零优化级别的帧指针,就像其他一些架构一样;这一定是我从中得到这个概念的原因。太棒了。这很好地解释了它。谢谢。