【发布时间】:2012-01-15 12:40:24
【问题描述】:
在下面的代码中,我在 signaling_thread_->Send(this, id, data); 的行中看到了一个段错误,它是从 PeerConnectionProxy 类的析构函数中调用的。
bool PeerConnectionProxy::Send(uint32 id, talk_base::MessageData* data) {
if (!signaling_thread_)
return false;
signaling_thread_->Send(this, id, data);
return true;
}
在 gdb 中运行,只要我对那行执行(gdb) step,我就会得到段错误和这个堆栈跟踪:
Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0xa782eed4 in webrtc::PeerConnectionProxy::Send (this=0xab889e80, id=6, data=0xbfffc1e8)
at third_party/libjingle/source/talk/app/webrtc/peerconnectionproxy.cc:219
#2 0xa782e91a in ~PeerConnectionProxy (this=0xab889e80, __in_chrg=<value optimised out>)
at third_party/libjingle/source/talk/app/webrtc/peerconnectionproxy.cc:145
...
就在那一行之前,我检查了signaling_thread_ 是非空的,正如预期的那样,这和数据也是如此。我很困惑是什么可能导致那里出现段错误或使堆栈最终达到 0x00000000。该代码仅在通过析构函数的代码路径上出现段错误。从许多其他地方调用发送函数没有问题。
2011-12-08 更新:
打开 stepi 和反汇编,我得到了这个:
0xa772eed2 219 signaling_thread_->Send(this, id, data);
0xa772eea4 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+24>: 8b 45 08 mov 0x8(%ebp),%eax
0xa772eea7 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+27>: 8b 40 0c mov 0xc(%eax),%eax
0xa772eeaa <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+30>: 8b 00 mov (%eax),%eax
0xa772eeac <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+32>: 83 c0 40 add $0x40,%eax
0xa772eeaf <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+35>: 8b 08 mov (%eax),%ecx
0xa772eeb1 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+37>: 8b 45 08 mov 0x8(%ebp),%eax
0xa772eeb4 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+40>: 8d 70 04 lea 0x4(%eax),%esi
0xa772eeb7 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+43>: 8b 45 08 mov 0x8(%ebp),%eax
0xa772eeba <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+46>: 8b 40 0c mov 0xc(%eax),%eax
0xa772eebd <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+49>: 8b 55 10 mov 0x10(%ebp),%edx
0xa772eec0 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+52>: 89 54 24 0c mov %edx,0xc(%esp)
0xa772eec4 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+56>: 8b 55 0c mov 0xc(%ebp),%edx
0xa772eec7 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+59>: 89 54 24 08 mov %edx,0x8(%esp)
0xa772eecb <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+63>: 89 74 24 04 mov %esi,0x4(%esp)
0xa772eecf <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+67>: 89 04 24 mov %eax,(%esp)
=> 0xa772eed2 <_ZN6webrtc19PeerConnectionProxy4SendEjPN9talk_base11MessageDataE+70>: ff d1 call *%ecx
ecx 是 0x0,所以这就是造成段错误的原因,但我仍然不明白发生了什么。该行的其他代码看起来与ecx 无关,除非我读错了。
【问题讨论】:
-
看起来可能是堆栈损坏。我建议在 Valgrind 下重新运行。
-
您是否通过
stepi而不是step获得更多信息? -
更新了 stepi 的结果。我仍在尝试让应用程序在 valgrind 中运行。
-
C++ 对象的一部分(在许多情况下)是一个虚拟表,用于处理
virtual方法。很可能,您的已损坏 - valgrind 也许 能够提供帮助。除此之外,您可以在 gdb 中使用数据访问断点来查找其损坏的时间。
标签: c++ segmentation-fault destructor