Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Crash within Qt Code using drag and drop (Qt BUG?)
QtWS25 Last Chance

Crash within Qt Code using drag and drop (Qt BUG?)

Scheduled Pinned Locked Moved General and Desktop
13 Posts 2 Posters 6.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    robby876
    wrote on last edited by
    #1

    Hi, I have an intermittent crash within the Qt Code. I have run it with the Qt sources and the crash occurs on: Line 1273 of qcoreapplication.cpp.

    It is due to a de-referenced pointer.

    @void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
    {
    if (receiver == 0) {
    qWarning("QCoreApplication::postEvent: Unexpected null receiver");
    delete event;
    return;
    }

    QThreadData * volatile * pdata = &receiver->d_func()->threadData;
    QThreadData *data = *pdata; <===================================== CRASH HERE
    if (!data) {
        // posting during destruction? just delete the event to prevent a leak
        delete event;
        return;
    }
    
    // lock the post event mutex
    data->postEventList.mutex.lock();
    
    // if object has moved to another thread, follow it
    while (data != *pdata) {
        data->postEventList.mutex.unlock();
    

    @

    This is within the drag->exec() function, however looks like it may be due to Qt posting application events.

    For more information please see the thread on stack overflow:

    http://stackoverflow.com/questions/14856836/unknown-intermittent-crash-due-dragging-and-dropping-in-qt

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Could you tells us more on what you try to achieve with drag & drop (It's not really clear from your code)

      Are you trying to move Widgets around ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • R Offline
        R Offline
        robby876
        wrote on last edited by
        #3

        The drag and drop code is quite long and covers a lot of possibilities. But essentially I am moving widgets about yes. I have two drop-able containers, one accepts one type of widget (A), the other takes another type (which is the container for the first type) (B).

        The first type (A) requires the newly created widget to be deleted if it is generated from the side bar menu or not if it is dragged from the container (B).

        The second type (B) requires the widget to be deleted if dragged from the sidebar, or not if dragged from the second type of droppable container.

        Its fairly complex but all works as it should. The intermittent bug occurs rarely but I have written some code to make the mouse move around dragging and dropping which speeds up its occurrence (It still can be replicated without).

        I will post up the stack trace from the bottom up (bottom level shown above):

        qdnd_x11.cpp
        @void QX11Data::xdndHandleFinished(QWidget *, const XEvent * xe, bool passive)
        {
        DEBUG("xdndHandleFinished");
        const unsigned long *l = (const unsigned long *)xe->xclient.data.l;

        DNDDEBUG << "xdndHandleFinished, l[0]" << l[0]
                 << "qt_xdnd_current_target" << qt_xdnd_current_target
                 << "qt_xdnd_current_proxy_targe" << qt_xdnd_current_proxy_target;
        
        if (l[0]) {
            int at = findXdndDropTransactionByWindow(l[0]);
            if (at != -1) {
                restartXdndDropExpiryTimer();
        
                QXdndDropTransaction t = X11->dndDropTransactions.takeAt(at);
                QDragManager *manager = QDragManager::self();
        
                Window target = qt_xdnd_current_target;
                Window proxy_target = qt_xdnd_current_proxy_target;
                QWidget *embedding_widget = current_embedding_widget;
                QDrag *currentObject = manager->object;
        
                qt_xdnd_current_target = t.target;
                qt_xdnd_current_proxy_target = t.proxy_target;
                current_embedding_widget = t.embedding_widget;
                manager->object = t.object;
        
                if (!passive)
                    (void) checkEmbedded(qt_xdnd_current_widget, xe);
        
                current_embedding_widget = 0;
                qt_xdnd_current_target = 0;
                qt_xdnd_current_proxy_target = 0;
        
                if (t.object)
                    t.object->deleteLater();  <========================
        
                qt_xdnd_current_target = target;
                qt_xdnd_current_proxy_target = proxy_target;
                current_embedding_widget = embedding_widget;
                manager->object = currentObject;
            }
        }
        waiting_for_status = false;
        

        }@

        qapplication_x11.cpp
        @
        X11->xdndHandleLeave(widget, event, passive_only);
        } else if (event->xclient.message_type == ATOM(XdndDrop)) {
        X11->xdndHandleDrop(widget, event, passive_only);
        } else if (event->xclient.message_type == ATOM(XdndFinished)) {
        X11->xdndHandleFinished(widget, event, passive_only); <============
        } else {
        if (passive_only) return 0;
        // All other are interactions
        }
        @

        qapplication_x11.cpp
        @
        case ClientMessage: // client message
        return x11ClientMessage(widget,event,False); <============
        @

        qguieventdispatcher_glib.cpp
        @
        // send through event filter
        if (source->q->filterEvent(&event))
        continue;

            if (qApp->x11ProcessEvent(&event) == 1)  <============
                return true;
        
            if (event.xany.serial >= marker)
                goto out;
        } while (XEventsQueued(X11->display, QueuedAfterFlush));
        

        out:
        @

        ....

        1 Reply Last reply
        0
        • R Offline
          R Offline
          robby876
          wrote on last edited by
          #4

          Since I have only been debugging with the Qt source today, I have seen it happens in more than one location in the function above.

          It seems to me to be the data pointer becomes invalid, if I could find out what this is then I would be able to trace it back, however, it is obtained from

          QThreadData * volatile * pdata = &receiver->d_func()->threadData;

          and d_func() doesn't seem accessible from the source I have.

          @

          }
          
          QThreadData * volatile * pdata = &receiver->d_func()->threadData;
          QThreadData *data = *pdata;
          if (!data) {
              // posting during destruction? just delete the event to prevent a leak
              delete event;
              return;
          }
          
          // lock the post event mutex
          data->postEventList.mutex.lock();
          
          // if object has moved to another thread, follow it
          while (data != *pdata) {
              data->postEventList.mutex.unlock();  <============= CRASH CAN ALSO HAPPEN HERE
          
              data = *pdata;
              if (!data) {
                  // posting during destruction? just delete the event to prevent a leak
                  delete event;
                  return;
          

          @

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            First thing that comes to my mind:
            Do you use the delete operator or deleteLater function from QObject ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • R Offline
              R Offline
              robby876
              wrote on last edited by
              #6

              Yes, in a number of places

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Sorry but, yes to what ?

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  robby876
                  wrote on last edited by
                  #8

                  I use both the delete and deletelater functions, on widgets and occasionally on the drag object (before exec() ) is called, it will not be called if it is deleted.

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    I would rather avoid using delete on widgets, unless you're really sure about the state of that widget (parenting etc...)

                    And since the drag object is a child of your current widget, it should also be automatically deleted.

                    And last thing, i would set _widget to 0 in the destructor of your custom QMimeData (or use something like a QPointer)

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      robby876
                      wrote on last edited by
                      #10

                      I need to delete the widget, if it is not dropped as it is created for being dragged into the container, if the drag fails it should be deleted, otherwise it will sit in memory until the application is closed.

                      The code that calls the deletion of the drag does not get called, it is only for if the creation of the widget fails, which does not happen.

                      I will set the widget to 0 in the destruction of the mime data, and see if this helps.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        Why do you create it there then ? Wouldn't it be safer to serialize your widget properties (i.e. in xml) and then use that to create the widget in the drop function ? So if no drop occurs, no need to handle that widget.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0
                        • R Offline
                          R Offline
                          robby876
                          wrote on last edited by
                          #12

                          Widgets can also be moved, from one place to another. These widgets are connected up to the backend via a (thread safe) shared control object and all setting show on the GUI match up. Due to this, it is far easier to create the widget and then destroy it if required.

                          I really don't think the issue is with deleting the widgets. As looking into the code, the object getting deleted is the QXdndDropTransaction object. This is handled by Qt itself.

                          1 Reply Last reply
                          0
                          • R Offline
                            R Offline
                            robby876
                            wrote on last edited by
                            #13

                            Done the changes to making the widget = 0 after destruction of the mime data, I've also removed a few deletes (temp change)... To no avail... I'm beginning to wonder if this is a bug in Qt.

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved