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

QMacCocoaViewContainer changes? phonon-backend-vlc causes crash in Qt Designer because of a superfluous foreign NSView release

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P1: Critical
    • 5.9
    • 5.8.0
    • QPA
    • None
    • Mac OS X 10.9.5, Qt 5.8.0, KF5 5.29.0, Phonon 4.9.1
    • macOS

    Description

      Something appears to have changed in Qt 5.8.0 with the way the QMacCocoaViewContainer class has to be used? I observe the following after updating from 5.7.1 to 5.8.0 :

      • Qt Designer crashes (during startup) when I have Phonon 4.9.x installed with the phonon-backend-vlc git/master backend (https://cgit.kde.org/phonon-vlc.git/).
      • the QMacCocoaViewContainer ctor now also calls QMacCocoaViewContainer::setCocoaView() when a NULL NSView pointer is given.
      • the QMacCocoaViewContainer example no longer releases the native view after passing it to setCocoaView(), despite what the documentation says, and despite the fact that setCocoaView indeed does a retain. Not releasing the VideoView instance in phonon-vlc's VlcMacWidget ctor also prevents the Designer crash but theoretically means the instance is being leaked.

      The Designer crash is preceded by the terminal output below and occurs in ~QMacCocoaViewContainer(), when doing `[nsview release]`. This means it's doing one release too many, as confirmed by the malloc error:

      qt.qpa.cocoa.window: NSView is not QNSView, consider checking for Qt::ForeignWindow
      qt.qpa.cocoa.window: NSView is not QNSView, consider checking for Qt::ForeignWindow
      Designer(97879,0x7fff721fd310) malloc: *** error for object 0x7fc7cf2a3300: pointer being freed was not allocated
      *** set a breakpoint in malloc_error_break to debug
      

      I have not been able to reproduce this in other applications than Qt Designer for now.

      In order to get a better idea of what's happening I added release and retain wrappers to phonon-vlc's VideoView class which produce some output. This is what I see (from the last retain call):

      2017-02-17 14:03:34.738 Designer[5236:d0f] Retaining <VideoView: 0x7fd20e406a00>, count=3, caller:
              1   CoreFoundation                      0x00007fff83391a56 -[NSMutableArray removeObject:] + 86
              2   AppKit                              0x00007fff8b569321 -[NSView _removeSubview:] + 222
              3   AppKit                              0x00007fff8b566067 -[NSView _setSuperview:] + 824
      2017-02-17 14:03:34.739 Designer[5236:d0f] Releasing <VideoView: 0x7fd20e406a00>, count=4, caller:
              1   CoreFoundation                      0x00007fff8333f43f CFRelease + 591
              2   CoreFoundation                      0x00007fff83394e3b -[__NSArrayM removeObjectAtIndex:] + 267
              3   CoreFoundation                      0x00007fff83391ab3 -[NSMutableArray removeObject:] + 179
              4   AppKit                              0x00007fff8b569321 -[NSView _removeSubview:] + 222
              5   AppKit                              0x00007fff8b566067 -[NSView _setSuperview:] + 824
      2017-02-17 14:03:34.740 Designer[5236:d0f] Releasing <VideoView: 0x7fd20e406a00>, count=3, caller:
              1   AppKit                              0x00007fff8b569321 -[NSView _removeSubview:] + 222
              2   AppKit                              0x00007fff8b566067 -[NSView _setSuperview:] + 824
              3   AppKit                              0x00007fff8b568f68 -[NSView removeFromSuperview] + 332
              4   AppKit                              0x00007fff8b587ab0 -[NSWindow setContentView:] + 74
              5   libqcocoa.dylib                     0x000000010dfc9fbc _ZN12QCocoaWindowD2Ev + 332
      2017-02-17 14:03:34.741 Designer[5236:d0f] Releasing <VideoView: 0x7fd20e406a00>, count=2, caller:
              1   libqcocoa.dylib                     0x000000010dfca23f _ZN12QCocoaWindowD2Ev + 975
              2   libqcocoa.dylib                     0x000000010dfca5c5 _ZThn16_N12QCocoaWindowD0Ev + 21
              3   QtGui                               0x0000000108dae557 _ZN7QWindow7destroyEv + 535
              4   QtWidgets                           0x00000001085aa8b4 _ZN14QWidgetPrivate16deleteTLSysExtraEv + 212
              5   QtWidgets                           0x00000001085aa58e _ZN7QWidget7destroyEbb + 830
      2017-02-17 14:03:34.742 Designer[5236:d0f] Releasing <VideoView: 0x7fd20e406a00>, count=1, caller:
              1   libobjc.A.dylib                     0x00007fff842e265a _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 502
              2   CoreFoundation                      0x00007fff8335e932 _CFAutoreleasePoolPop + 50
              3   Foundation                          0x00007fff82105437 -[NSAutoreleasePool drain] + 147
              4   QtCore                              0x000000010962e0b4 _ZN19QMacAutoReleasePoolD1Ev + 20
              5   libqcocoa.dylib                     0x000000010dfca26d _ZN12QCocoaWindowD2Ev + 1021
      

      phonon-vlc allocates its VideoView instance within the scope of a local, temporary NSAutoreleasePool so seeing the instance being release by QMacAutoReleasePool::~QMacAutoReleasePool() surprises me a bit but is probably to be expected.

      I tried to check if this is related to (mis)using ARC but the crash still occurs after converting phonon-vlc to ARC (which is just a matter of removing the explicit VideoView instance release and @autoreleasepool instead of creating one explicitly).

      The crash backtrace isn't helpful with ARC:

      (lldb) bt all
      * thread #1: tid = 0xa36530, 0x00007fff896eee20 libsystem_kernel.dylib`__wait4 + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
        * frame #0: 0x00007fff896eee20 libsystem_kernel.dylib`__wait4 + 8
          frame #1: 0x000000011c6a9cee libKF5Crash.5.dylib`KCrash::startProcess(int, char const**, bool) [inlined] startProcessInternal(argc=<unavailable>, directly=<unavailable>) + 125 at kcrash.cpp:649
          frame #2: 0x000000011c6a9c71 libKF5Crash.5.dylib`KCrash::startProcess(argc=<unavailable>, argv=<unavailable>, waitAndExit=<unavailable>) + 17 at kcrash.cpp:631
          frame #3: 0x000000011c6a9ab5 libKF5Crash.5.dylib`KCrash::defaultCrashHandler(sig=11) + 1061 at kcrash.cpp:528
          frame #4: 0x00007fff8961c5aa libsystem_platform.dylib`_sigtramp + 26
          frame #5: 0x00007fff842e0098 libobjc.A.dylib`objc_msgSend + 24
      

      but a bit more so without:

      (lldb) bt all
      * thread #1: tid = 0xa37009, 0x00007fff896eee20 libsystem_kernel.dylib`__wait4 + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
        * frame #0: 0x00007fff896eee20 libsystem_kernel.dylib`__wait4 + 8
          frame #1: 0x000000012329fcee libKF5Crash.5.dylib`KCrash::startProcess(int, char const**, bool) [inlined] startProcessInternal(argc=<unavailable>, directly=<unavailable>) + 125 at kcrash.cpp:649
          frame #2: 0x000000012329fc71 libKF5Crash.5.dylib`KCrash::startProcess(argc=<unavailable>, argv=<unavailable>, waitAndExit=<unavailable>) + 17 at kcrash.cpp:631
          frame #3: 0x000000012329fab5 libKF5Crash.5.dylib`KCrash::defaultCrashHandler(sig=6) + 1061 at kcrash.cpp:528
          frame #4: 0x00007fff8961c5aa libsystem_platform.dylib`_sigtramp + 26
          frame #5: 0x00007fff896ee867 libsystem_kernel.dylib`__pthread_kill + 11
          frame #6: 0x00007fff87fc4c7c libsystem_malloc.dylib`szone_free + 2350
          frame #7: 0x00007fff89cb3b26 libsystem_c.dylib`abort + 125
          frame #8: 0x00007fff87fd207f libsystem_malloc.dylib`free + 411
          frame #9: 0x00007fff842e23a4 libobjc.A.dylib`object_dispose + 54
          frame #10: 0x00007fff8b5a0240 AppKit`-[NSResponder dealloc] + 126
          frame #11: 0x00007fff8b59e35f AppKit`-[NSView dealloc] + 182
          frame #12: 0x000000011bdea3ec phonon_vlc.so`-[VideoView release](self=0x00007f815d404a20, _cmd=<unavailable>) + 268 at nsvideoview.mm:91
          frame #13: 0x0000000110b23f93 QtWidgets`QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate() [inlined] QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate(this=0x00007f815d403490) + 41 at qmaccocoaviewcontainer_mac.mm:113
          frame #14: 0x0000000110b23f6a QtWidgets`QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate() [inlined] QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate(this=0x00007f815d403490) at qmaccocoaviewcontainer_mac.mm:110
          frame #15: 0x0000000110b23f6a QtWidgets`QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate(this=0x00007f815d403490) + 10 at qmaccocoaviewcontainer_mac.mm:110
          frame #16: 0x000000011177e1d1 QtCore`QObject::~QObject() [inlined] QScopedPointerDeleter<QObjectData>::cleanup(pointer=<unavailable>) + 2049 at qscopedpointer.h:60
          frame #17: 0x000000011177e1c6 QtCore`QObject::~QObject() [inlined] QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData> >::~QScopedPointer() + 4 at qscopedpointer.h:107
          frame #18: 0x000000011177e1c2 QtCore`QObject::~QObject() [inlined] QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData> >::~QScopedPointer() at qscopedpointer.h:105
          frame #19: 0x000000011177e1c2 QtCore`QObject::~QObject(this=<unavailable>) + 2034 at qobject.cpp:1049
          frame #20: 0x000000011078ae00 QtWidgets`QWidget::~QWidget(this=0x00007f815d403280) + 1248 at qwidget.cpp:1714
          frame #21: 0x000000011bde1d7e phonon_vlc.so`Phonon::VLC::VideoWidget::~VideoWidget() [inlined] QHash<QByteArray, double>::~QHash() + 142 at vlcmacwidget.h:25
          frame #22: 0x000000011bde1d76 phonon_vlc.so`Phonon::VLC::VideoWidget::~VideoWidget() [inlined] Phonon::VLC::VideoWidget::~VideoWidget(this=0x00007f815d403280) + 125 at videowidget.cpp:206
          frame #23: 0x000000011bde1cf9 phonon_vlc.so`Phonon::VLC::VideoWidget::~VideoWidget() [inlined] Phonon::VLC::VideoWidget::~VideoWidget(this=0x00007f815d403280) at videowidget.cpp:203
          frame #24: 0x000000011bde1cf9 phonon_vlc.so`Phonon::VLC::VideoWidget::~VideoWidget(this=0x00007f815d403280) + 9 at videowidget.cpp:203
          frame #25: 0x000000012369c5be libphonon4qt5.4.dylib`Phonon::MediaNodePrivate::~MediaNodePrivate(this=0x00007f8159479a20) + 110 at medianode.cpp:72
          frame #26: 0x00000001236b1084 libphonon4qt5.4.dylib`Phonon::VideoWidgetPrivate::~VideoWidgetPrivate() [inlined] Phonon::AbstractVideoOutputPrivate::~AbstractVideoOutputPrivate() + 36 at abstractvideooutput_p.h:34
          frame #27: 0x00000001236b107c libphonon4qt5.4.dylib`Phonon::VideoWidgetPrivate::~VideoWidgetPrivate() [inlined] Phonon::VideoWidgetPrivate::~VideoWidgetPrivate(this=0x00007f8159479a20) + 19 at videowidget_p.h:35
          frame #28: 0x00000001236b1069 libphonon4qt5.4.dylib`Phonon::VideoWidgetPrivate::~VideoWidgetPrivate() [inlined] Phonon::VideoWidgetPrivate::~VideoWidgetPrivate(this=0x00007f8159479a20) at videowidget_p.h:35
          frame #29: 0x00000001236b1069 libphonon4qt5.4.dylib`Phonon::VideoWidgetPrivate::~VideoWidgetPrivate(this=0x00007f8159479a20) + 9 at videowidget_p.h:35
          frame #30: 0x00000001236b10f2 libphonon4qt5.4.dylib`Phonon::VideoWidget::~VideoWidget() [inlined] Phonon::AbstractVideoOutput::~AbstractVideoOutput() + 18 at abstractvideooutput.h:51
          frame #31: 0x00000001236b10e9 libphonon4qt5.4.dylib`Phonon::VideoWidget::~VideoWidget() [inlined] Phonon::VideoWidget::~VideoWidget(this=0x00007f815946fbd0) at videowidget.h:54
          frame #32: 0x00000001236b10e9 libphonon4qt5.4.dylib`Phonon::VideoWidget::~VideoWidget() [inlined] Phonon::VideoWidget::~VideoWidget(this=0x00007f815946fbd0) at videowidget.h:54
          frame #33: 0x00000001236b10e9 libphonon4qt5.4.dylib`Phonon::VideoWidget::~VideoWidget(this=0x00007f815946fbd0) + 9 at videowidget.h:54
          frame #34: 0x00000001101f5f76 QtDesigner`qdesigner_internal::WidgetDataBase::defaultPropertyValues(this=<unavailable>, name=<unavailable>) + 358 at widgetdatabase.cpp:444
          frame #35: 0x00000001101f616a QtDesigner`qdesigner_internal::WidgetDataBase::grabDefaultPropertyValues(this=0x00007f8159506400) + 106 at widgetdatabase.cpp:453
          frame #36: 0x000000010fb43c0d Designer`QDesignerWorkbench::QDesignerWorkbench(this=0x00007f815976ca40) + 317 at qdesigner_workbench.cpp:186
          frame #37: 0x000000010fb40ac5 Designer`QDesigner::parseCommandLineArguments(this=0x00007fff500d6ca0) + 4613 at qdesigner.cpp:251
          frame #38: 0x000000010fb3f1d8 Designer`main(argc=1, argv=<unavailable>) + 72 at main.cpp:45
          frame #39: 0x00007fff8a91f5fd libdyld.dylib`start + 1
          frame #40: 0x00007fff8a91f5fd libdyld.dylib`start + 1
      
      • Also note the "qt.qpa.cocoa.window: NSView is not QNSView, consider checking for Qt::ForeignWindow" warnings. They come from qnsview_cast() . They're a bit counterproductive here because the use of non-QNSView classes is expected and intended when using QMacCocoaViewContainer. Ideally it should be at most a qCDebug() level message when QMacCocoaViewContainer or QMacNativeWidget are used.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            vestbo Tor Arne Vestbø
            rjvbertin René Bertin
            Votes:
            2 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes