LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1323|回复: 3

请问这个gdb提示的错误是什么原因?

[复制链接]
发表于 2004-12-16 18:03:27 | 显示全部楼层 |阅读模式
pure virtual method called

Program received signal SIGABRT, Aborted.
[Switching to Thread 65541 (LWP 5042)]
0x407e05c1 in kill () from /lib/libc.so.6
(gdb) up
#1  0x4069258d in pthread_kill () from /lib/libpthread.so.0
(gdb) up
#2  0x4069290b in raise () from /lib/libpthread.so.0
(gdb) up
#3  0x407e0364 in raise () from /lib/libc.so.6
(gdb) up
#4  0x407e189b in abort () from /lib/libc.so.6
(gdb) up
#5  0x08077a97 in __cxxabiv1::__terminate(void (*)()) ()
(gdb) up
#6  0x08077ae4 in std::terminate() ()
(gdb) up
#7  0x08076e77 in __cxa_pure_virtual ()
(gdb) up
#8  0x0805dd4e in Player::_start_routine(void*) (arg=0x80f3f98) at mediaplayer/player.cpp:250



player.cpp:250内容如下:
pPlayer->m_pDecoder->play();

这个Decoder::play()是一个pure virtual function,在这里pPlayer->m_pDecoder是一个MP3Decoder,继承于Decoder


注明:程序在播放一首歌曲的时候实际上是一个独立的线程,在切换歌曲的时候一般运行正常,但是如果切换速度非常快,切了几首就会出现gdb上面的提示。可能是什么原因?
发表于 2004-12-26 23:11:16 | 显示全部楼层
我以前在写一个C++线程库时也遇上过类似的问题,大体的原因是这样的:

1. 你的线程A中存在一个多态对象(有虚函数);
2. 你的另一个线程B中正打算通过该多态对象调用了虚函数;
3. 这时线程发生切换,转换到线程A,线程A退出,而对象被析构,此时其虚函数表被置空;
4. 线程被切换回B,B按照前面的代码调用虚函数,此时虚函数指针为空,所以引发异常。

通常情况下这种问题不会出现,是因为这种竟态条件没有出现,而且由于该条件触发的是GCC的内部代码,所以出错时会打印出一大堆莫名其妙的函数调用信息。

当然,你遇到的具体情况也不一定就和我遇到的一模一样,但是原理上应该是一样的,就是竟态问题。你可以试试引入一个同步量(可以用条件变量实现),保证两个线程的调用顺序,一般就可以解决问题。
 楼主| 发表于 2004-12-27 09:32:01 | 显示全部楼层
非常感谢,已经解决。听君一席话,让我恍然大悟。
发表于 2009-4-21 12:59:33 | 显示全部楼层
我也遇到了相同的问题,受教了,非常感谢!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表