关闭

Qt编程中诡异的段错误

3726人阅读 评论(3) 收藏 举报
编程中让人郁闷的事情莫过于段错误(也就是传说中的Core dumped),让人更郁闷的情况是有时候段错误,有时候又不段错误。而基于第三方库开发的应用程序,当出现段错误时,更是难以调试,因为段错误的代码可能是在库代码中,这导致GDB工具也无法给出有用的调试信息。
要是真碰到这种情况,只能仰天长叹了!
前几天在把Opencv和Qt4结合起来,完成从摄像头捕捉视频,并显示出来的问题时,就遇到了这种段错误。出现段错误时给出的出错信息如下:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 8086cc8. Receiver '' (of type 'QSocketNotifier') was created in thread 8052280", file kernel/qcoreapplication.cpp, line 253
忽略 (core dumped)
以前只用Opencv完成这部分功能的时候,用到了Boost线程库实现的多线程,让视频显示部分的代码在一个新线程中执行,主线程就不会被阻塞。现在用Opencv结合Qt4来实现这部分功能,多线程部分就使用了QThread。(重载QThread的run())

void MyThread::run(){
    QImage image;
    signal 
= VIDEO_PAUSE;
    
while((pImage = cvQueryFrame(pCapture)) != NULL){
        
if(signal == VIDEO_START){
            cvWriteFrame(videowriter, pImage);
            emit RenderImage(IplImageToQImage(pImage));
        }

        
else if(signal == VIDEO_STOP)
            
break;
        cvWaitKey(
2);
    }

}

原本的程序是在循环里面用update()发出一个paintEvent()事件来刷新图像的,后来看了错误信息,知道了事件是不能在两个线程之间发送的,于是通过发送信号signal/slot的方式来实现目的,即上述线程向主线程发送一个signal(带QImage),主线程接收这个信号并在本线程内update()一个paintEvent()事件,这样一来,就不会在两个线程之间发送事件了。
本以为问题就此解决,可以洗个脚回去睡觉了!结果还是段错误,而且错误信息也还是一样。于是其后有一段时间都在自我否定中,让我对开始的一系列推理和做法将信将疑。
在其后长达n个小时的时间里,我试着去掉一些代码,来看看是否会有段错误的发生,结果依然还是段错误。终于后来感动上天....
那一夜,俱乐部,包宿....就在11点多钟的时候:
我把cvWaitKey(2)去掉,然后编译,运行程序,运行了一分多钟没有出现段错误,但我还不能确信,因为有时候就是跑了一分多钟才段错误的,于是我一直等着...结果终于没有再段错误了。
原因分析:在Opencv窗口显示中需要包含cvWaitKey(?)否则窗口无法显示出来,因此我一直认为在Qt中显示,它也应该需要。不想竟是它出了问题,cvWaitKey(?)调用了系统定时器,因此可能会向该进程的所有线程发送一个事件,于是便导致了在两个线程之间发送事件的错误。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21794次
    • 积分:316
    • 等级:
    • 排名:千里之外
    • 原创:9篇
    • 转载:0篇
    • 译文:0篇
    • 评论:9条
    文章存档
    最新评论