【发布时间】:2009-10-29 20:26:24
【问题描述】:
我正在调查一个死锁错误。我用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() 的调用。这个函数不会调用自己,也不会调用任何回调它的函数……它不是递归的。那为什么它会在堆栈中出现两次呢?
这是调试器创建的人工制品,还是真的?
您会注意到最里面的调用正在等待互斥锁 - 我认为这可能是我的死锁。 Service::releaseObject() 锁定了一个互斥体,所以如果它神奇地传送回自身内部,那么肯定会发生死锁。
一些背景:
这是在 RHEL4 上使用 g++ v3.4.6 编译的。这是一个 64 位操作系统,但这是 32 位代码,使用 -m32 编译。它在 -O3 进行了优化。我不能保证应用程序代码是使用与 LIBFOO 代码完全相同的选项编译的。
Service 类没有虚函数,所以没有 vtable。 RequesterImpl 类继承自全虚拟接口,因此它确实有一个 vtable。
【问题讨论】:
标签: c++ linux debugging gdb g++