c++ - 如何防止QT事件堆栈溢出?

标签 c++ linux qt

我正在制作一个QT应用程序,它根据从套接字接收到的信息来更新窗口。这就是我这样做的方式:

  • 设置一个计时器,使应用程序检查套接字
  • 收到新信息(如果有)之后的
  • ,我更改用于绘制小部件的上下文数据并对其调用重绘
  • 自然,我执行绘图所需的代码在绘画事件


  • 但是,我遇到了一个问题。该应用程序不稳定,并且会随机崩溃(通常是在发送到套接字后启动)。在调试下,堆栈跟踪显示它在QT本身的深度崩溃,在另一个绘画事件的分配上(我认为,由堆栈判断)。

    如何防止这种情况发生?也许,如果绘画还没有完成,就不打电话给redraw吗?

    处理接收新数据的代码; dt.listen()返回更改的项目数。
    void CommandPanel::update()
    {
        //printf("Some drawing is done!\n");
        static int udel = 0;
        udel += 1+dt.listen();
        if ( udel > 40)
        {
            this->repaint(); //!!!
            udel = 0;
        }
    }
    

    将其绑定(bind)到计时器的代码
    //object T that is derived from QWidget is created
    QTimer timer;
    QObject::connect(&timer, SIGNAL(timeout()), &T, SLOT(update()));
    timer.start(1000 / 10);
    T.show();
    

    在调试下,当我到达“!!!”行时,我收到分段错误信号在评论中。这是完整的堆栈跟踪。

    线程3(线程0xb75b9b70(LWP 9183)):
    __kernel_vsyscall中的_#0 0x0012e416()
    没有可用的符号表信息。

    来自/lib/i386-linux-gnu/libpthread.so.0的pthread_cond_timedwait @@ GLIBC_2.3.2()中的_#1 0x00e49834
    没有可用的符号表信息。

    _#2 0x01472f0e in ?? ()来自/usr/lib/i386-linux-gnu/libgthread-2.0.so.0
    没有可用的符号表信息。

    _#3 0x0114042c in ?? ()来自/lib/i386-linux-gnu/libglib-2.0.so.0
    没有可用的符号表信息。

    来自/lib/i386-linux-gnu/libglib-2.0.so.0的g_async_queue_timed_pop()中的_#4 0x01140f6d
    没有可用的符号表信息。

    _#5 0x01198980 in ?? ()来自/lib/i386-linux-gnu/libglib-2.0.so.0
    没有可用的符号表信息。

    _#6 0x011962df in ?? ()来自/lib/i386-linux-gnu/libglib-2.0.so.0
    没有可用的符号表信息。

    /lib/i386-linux-gnu/libpthread.so.0中start_thread()中的_#7 0x00e44e99
    没有可用的符号表信息。

    来自/lib/i386-linux-gnu/libc.so.6的克隆()中的_#8 0x0105573e
    没有可用的符号表信息。

    线程2(线程0xb7dbab70(LWP 9072)):
    __kernel_vsyscall中的_#0 0x0012e416()
    没有可用的符号表信息。

    _#1 0x01046f76在/lib/i386-linux-gnu/libc.so.6中的poll()中
    没有可用的符号表信息。

    来自/lib/i386-linux-gnu/libglib-2.0.so.0的g_poll()中的_#2 0x0117d84b
    没有可用的符号表信息。

    _#3 0x0116d1af in ?? ()来自/lib/i386-linux-gnu/libglib-2.0.so.0
    没有可用的符号表信息。

    来自/lib/i386-linux-gnu/libglib-2.0.so.0的g_main_loop_run()中的_#4 0x0116d92b
    没有可用的符号表信息。

    _#5 0x0166b304 in ?? ()来自/usr/lib/i386-linux-gnu/libgio-2.0.so.0
    没有可用的符号表信息。
    _#6 0x011962df in ?? ()来自/lib/i386-linux-gnu/libglib-2.0.so.0
    没有可用的符号表信息。

    /lib/i386-linux-gnu/libpthread.so.0中start_thread()中的_#7 0x00e44e99
    没有可用的符号表信息。

    来自/lib/i386-linux-gnu/libc.so.6的clone()中的_#8 0x0105573e
    没有可用的符号表信息。

    线程1(线程0xb7fe4710(LWP 8938)):
    来自/usr/lib/libQtCore.so.4的QMetaObject::activate(QObject *,QMetaObject const *,int,void **)()中的_#0 0x00d183f8
    没有可用的符号表信息。

    来自/usr/lib/libQtCore.so.4的QTimer::timeout()()中的_#1 0x00d652f7
    没有可用的符号表信息。

    来自/usr/lib/libQtCore.so.4的QTimer::timerEvent(QTimerEvent *)()中的_#2 0x00d1e3ee
    没有可用的符号表信息。

    /usr/lib/libQtCore.so.4中的QObject::event(QEvent *)()中的_#3 0x00d17214
    没有可用的符号表信息。

    来自/usr/lib/libQtGui.so.4的QApplicationPrivate::notify_helper(QObject *,QEvent *)()中的_#4 0x0025cd24
    没有可用的符号表信息。

    来自/usr/lib/libQtGui.so.4的QApplication::notify(QObject *,QEvent *)()中的_#5 0x002618ce
    没有可用的符号表信息。

    来自/usr/lib/libQtCore.so.4的QCoreApplication::notifyInternal(QObject *,QEvent *)()中的_#6 0x00d020bb
    没有可用的符号表信息。

    _#7 0x00d321e4 in ?? ()来自/usr/lib/libQtCore.so.4
    没有可用的符号表信息。

    _#8 0x00d2ee27 in ?? ()来自/usr/lib/libQtCore.so.4
    没有可用的符号表信息。

    来自/lib/i386-linux-gnu/libglib-2.0.so.0的g_main_context_dispatch()中的_#9 0x0116caa8
    没有可用的符号表信息。

    _#10 0x0116d270 in ?? ()来自/lib/i386-linux-gnu/libglib-2.0.so.0
    没有可用的符号表信息。

    来自/lib/i386-linux-gnu/libglib-2.0.so.0的g_main_context_iteration()中的_#11 0x0116d524
    没有可用的符号表信息。

    来自/usr/lib/libQtCore.so.4的QEventDispatcherGlib::processEvents(QFlags)()中的_#12 0x00d2f53c
    没有可用的符号表信息。

    _#13 0x00310775 in ?? ()来自/usr/lib/libQtGui.so.4
    没有可用的符号表信息。

    来自/usr/lib/libQtCore.so.4的QEventLoop::processEvents(QFlags)()中的_#14 0x00d01289
    没有可用的符号表信息。

    来自/usr/lib/libQtCore.so.4的QEventLoop::exec(QFlags)()中的_#15 0x00d01522
    没有可用的符号表信息。

    /usr/lib/libQtCore.so.4中的QCoreApplication::exec()()中的_#16 0x00d05ecc
    没有可用的符号表信息。

    /usr/lib/libQtGui.so.4中QApplication::exec()()中的_#17 0x0025a8e7
    没有可用的符号表信息。

    _#18 0x0804ac19位于../wargui/main.cpp:40的main(argc = 1,argv = 0xbffff8a4)中
        app = <incomplete type>
        timer = <incomplete type>
        T = {<QLabel> = {<No data fields>}, view = 0x10e33c0, dt = {qflag = 0, channelSockets = {0x8566108 "/tmp/channel1", 0x8567788 "/tmp/channel2", 0x8565298 "/tmp/channel3", 0x8565330 "/tmp/channel4", 0x8567db8 "/tmp/channel5", 0x8567e00 "/tmp/channel6", 0x8567108 "/tmp/channel7"}, mesSources = {0x8567e78, 0x85653a0, 0x85652b0, 0x8565348, 0x8567dd0, 0x85670d8, 0x8567120}, cossock = 33, chansocks = {26, 27, 28, 29, 30, 31, 32}, logLength = {0, 0, 0, 0, 0, 0, 0, 1, 1}, logs = {0x8568620, 0x8568788, 0x85688f0, 0x8568a58, 0x8568bc0, 0x8568d28, 0x8568e90, 0x8568ff8, 0x8569160}, targets = 0x85651e0}}
        pm = <incomplete type>
        r = -1073743880
    

    我还必须添加以下内容。
    如果qt应用程序在消息开始到达套接字之前已经启动,则它可以正常工作。否则,当已经发送了消息然后启动qt应用程序时,一旦对update()进行首次调用,它就会掉落。

    最佳答案

    第一次覆盖update()方法时,我遇到了此类问题。

    Gnud是正确的,直接调用原始update()应该可以解决您的问题,如果在发生绘画事件时有事要做/绘制/更新/绘画,请重新实现paintEvent(QPaintEvent*)

    除此之外,为了触发绘画事件,您可以将插槽连接到readyRead() QSocket信号。在此插槽中,您可以评估bytesAvailable(),直到达到相当数量的数据为止。然后,您调用update()。您还应该创建/重置一个触发计时器,以防万一您刚收到的数据是最后一个,并且永远都无法达到“体面”的数量!

    关于c++ - 如何防止QT事件堆栈溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6036971/

    相关文章:

    c++ - "<<"和 ">>"运算符如何进行 I/O?

    java - 如何将n个数字相加,相乘到数组中的给定范围,并以O(n)时间反转数组中的范围?

    linux - 使用 eclipse 在 linux 上进行 qt 开发?

    c++ - Mac 上的 Qt Creator 中无法链接 pylon 框架

    c++ - 删除 "fixed"流操纵器时出现问题

    c++ - 没有溢出的无限递归 - 这可能吗?

    linux - 在运行时加载 Linux 库

    linux - 合并排序的文件,缓冲最少

    linux - 共享库符号冲突和静态链接(在 Linux 上)

    c++ - Qml - 在 C++ 类和由 QmlRegisterType 创建的类之间交换日期