Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-54832

[macOS] crash on exit after drag-n-drop

    XMLWordPrintable

Details

    • macOS
    • ad0d2f463a0905c4705660d96e8a514539c51d36 64475272a251b3ba773fec4bc6d00cfe46d1854b

    Description

      symptoms:

      • load a qt-based plugin
      • start a 'drag' operation of a text
      • terminate the host
      • crash

      stack trace:
      stack trace:
      > Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
      > 0 com.apple.CoreFoundation 0x00007fff940f3662 CFPasteboardGetGenerationCount + 66
      > 1 com.apple.HIServices 0x00007fff894693ad IndexToItem(OpaquePasteboardRef*, long) + 30
      > 2 com.apple.HIServices 0x00007fff8948c46c PasteboardCopyDataProc(void*, __CFPasteboard*, long, long, __CFString const*) + 190
      > 3 com.apple.CoreFoundation 0x00007fff941a6e1b __CFPasteboardResolvePromiseForItemLocal + 539
      > 4 com.apple.CoreFoundation 0x00007fff94176a75 CFPasteboardResolveAllPromisedData + 757
      > 5 com.apple.CoreFoundation 0x00007fff941a170c _CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER_ + 12
      > 6 com.apple.CoreFoundation 0x00007fff941a167f ___CFXRegistrationPost_block_invoke + 63
      > 7 com.apple.CoreFoundation 0x00007fff941a0d47 _CFXRegistrationPost + 407
      > 8 com.apple.CoreFoundation 0x00007fff941a0ab2 ___CFXNotificationPost_block_invoke + 50
      > 9 com.apple.CoreFoundation 0x00007fff9419ad42 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1922
      > 10 com.apple.CoreFoundation 0x00007fff94089145 _CFXNotificationPost + 693
      > 11 com.apple.Foundation 0x00007fff8c32d921 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
      > 12 com.apple.AppKit 0x00007fff89c1490c -[NSApplication terminate:] + 1696

      doing some tracing i figured out that this crash happens after the
      QMacPasteboards have been destroyed.

      > QMacPasteboard::~QMacPasteboard()
      > {
      > // commit all promises for paste after exit close
      > for (int i = 0; i < promises.count(); ++i)

      { > const Promise &promise = promises.at(i); > // At this point app teardown has started and control is somewhere in the Q[Core]Application > // destructor. Skip "lazy" promises where the application has not provided data; > // the application will generally not be in a state to provide it. > if (promise.dataRequestType == LazyRequest) > continue; > QCFString flavor = QCFString(promise.convertor->flavorFor(promise.mime)); > NSInteger pbItemId = promise.itemId; > promiseKeeper(paste, reinterpret_cast<PasteboardItemID>(pbItemId), flavor, this); > }

      >
      > if (paste)
      > CFRelease(paste);
      > }

      apparently "lazy" promises are not cleaned up, which seems to be done on
      purpose: https://codereview.qt-project.org/#/c/95091/

      if i remove of if(lazyrequest) call, the crash disappears.

      morten sorvig's comment:

      The intended behavior of “lazy" promises is to delay pulling the data from
      the application until the drop/paste happens and the target data type/flavor
      is known.

      “eager” promises can leave data behind after app exit, but as the comment
      states I did not want to pull data from he application at shutdown time
      for the lazy type.

      I’d then like to find some way to cancel/resolve the promises without application
      data. Provide fake (empty) data?

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-54832
          # Subject Branch Project Status CR V

          Activity

            People

              tpochep Timur Pocheptsov
              timblechmann tim blechmann
              Votes:
              2 Vote for this issue
              Watchers:
              9 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes