Important: Please read the Qt Code of Conduct -

Weird crash with QSystemTrayIcon on OSX

  • I have a Qt 4.8.4 application that I'm maintaining that is seeing a peculiar crash on OSX, and I'm having a difficult time understanding what is going on. The application has two modes - in the in-program mode, it has a QMainWindow that owns a QSystemTrayIcon. The application can quit back to it's pre-program mode where it has a different QMainWindow that doesn't have the QSystemTrayIcon.

    When we switch from our in-program QMainWindow back to our pre-program QMainWindow, the QSystemTrayIcon gets deleted (I've derived from it and checked when the destructor gets called), but sometimes after the QSystemTrayIcon object is deleted, the program segfaults. The stack trace we see is:

    @Thread 0 Crashed:: Dispatch queue:
    0 libobjc.A.dylib 0x919914ab objc_msgSend + 27
    1 libQtGui_debug.4.dylib 0x01bc11b8 -[QNSImageView drawRect:] + 56
    2 0x9926b833 -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inGraphicsContext:CGContext:topView:shouldChangeFontReferenceColor:] + 1125
    3 0x993a8077 -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inContext:topView:] + 110
    4 0x993a7f9e -[NSView _drawRectBasedDisplayRectIgnoringOpacity:inContext:] + 268
    5 0x993a7cbe -[NSView displayRectIgnoringOpacity:inContext:] + 492
    6 0x99427f06 __46-[NSView cacheDisplayInRect:toBitmapImageRep:]_block_invoke + 397
    7 0x99427c8f __36-[NSBitmapImageRep _captureDrawing:]_block_invoke + 553
    8 0x9917c9af -[NSBitmapImageRep _performBlockUsingBacking:] + 43
    9 0x994279dd -[NSBitmapImageRep _captureDrawing:] + 199
    10 0x99427901 -[NSView cacheDisplayInRect:toBitmapImageRep:] + 161
    11 0x9980c032 -[NSStatusItem _updateReplicant:] + 809
    12 0x9941a7dd __33-[NSStatusItem _updateReplicants]_block_invoke + 187
    13 0x9941a6d5 -[NSSystemStatusBar _withAdjustmentDeferred:] + 69
    14 0x9941a67b -[NSStatusItem _updateReplicants] + 170
    15 0x9980d144 -[NSStatusItem _updateReplicantsUnlessMenuIsTracking:] + 301
    16 0x9bb8427c __NSFireDelayedPerform + 422
    18 0x939a5863 __CFRunLoopDoTimer + 1395
    19 0x93a2006d __CFRunLoopDoTimers + 349
    20 0x9395d353 __CFRunLoopRun + 1779
    21 0x9395c9ea CFRunLoopRunSpecific + 394
    22 0x9395c84b CFRunLoopRunInMode + 123
    23 0x97d0cb5d RunCurrentEventLoopInMode + 259
    24 0x97d0c777 ReceiveNextEventCommon + 163
    25 0x97d0c6bd _BlockUntilNextEventMatchingListInModeWithFilter + 92
    26 0x99102349 _DPSNextEvent + 1602
    27 0x99101870 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 119
    28 libQtGui_debug.4.dylib 0x01b43875 QEventDispatcherMac::processEvents(QFlagsQEventLoop::ProcessEventsFlag) + 2215
    29 libQtCore_debug.4.dylib 0x016abce0 QCoreApplication::processEvents(QFlagsQEventLoop::ProcessEventsFlag) + 180
    30 com.ourcompany.ourapp 0x00166875 View_Qml::processEvents() + 69 (view_qml.cpp:451)

    This is happening well after the QSystemTrayIcon has been deleted. When this crash happens, even though the QSystemTrayIcon has been deleted and I'm seeing the pre-program QMainWindow, the system tray icon in the system menubar is still there - as if the QSystemTrayIcon hasn't been deleted.

    There's an outstanding bug ( thats been around since the 4.7 days and looks suspiciously similar, but there are still differences. I'm inclined to think that I'm doing something wrong here, but short of some great enlightenment here in the forum, my next step is to try to figure out why QSystemTrayIcon can't seem to get rid of the NSStatusItem that it's wrapping.

    Can anyone suggest anything?

  • Moderators

    What happens if you call QSystemTrayIcon->hide() before you delete it. Also try using QSystemTrayIcon->deleteLater() instead of delete QSystemTrayIcon;.

    Sometimes there are things pending for the object and calling deleteLater allows the event loop (where you are crashing) to process the signals and events then delete the item automatically for you. This can prevent crashes in certain circumstances and could be your issue right here.

  • We've tried multiple variations of this. We've tried
    @delete m_sysTrayIcon;

    We've tried

    We've tried

    We would have tried

    ...but QSystemTrayIcon doesn't have a close() method!

    In every one of these cases, our QSystemTrayIcon gets nicely deleted (according to the printout we have in our dtor), but we still get the crash.

    QSystemTrayIcon seems to be a very odd beast, being renderable but not descended from QWidget. The Windows build of this code works perfectly, and has for some time now. But the OSX version gets this mysterious crash.

  • Lifetime Qt Champion


    Can you try with the latest current version that is 4.8.6 ?

  • Ok - I'll try it with 4.8.6. Our application is still 32-bit so unfortunately this isn't as simple as dropping in a binary update - I have to put together a special 32-bit build.

  • Lifetime Qt Champion

    Then first try with the pre-built package, it should crash the same unless you are doing a special build

  • Is there a prebuilt 32-bit OSX build? If so I'd gladly use that. I wasn't aware that such a thing existed.

  • Lifetime Qt Champion

    No, there's no 32Bit build since a long time. Just the 64, but Qt is not really hard to compile on OS X

  • I'm running into a whole lot of build breaks with 4.8.6 and the latest xcode in 32-bit. I'm making a lot of patches to get 4.8.6 to build, and I've completely given up on phonon.

    Are 32-bit OSX builds part of your continuous integration system? It seems like recent versions of clang have broken a whole lot of things in Qt...

  • Moderators

    What if instead of completely deleting the system tray icon you just hide it in the mode where you don't want to display it?

    Does that cause a crash too? Or is it just the cleanup? Then you can create it, show it when you want, hide it when you don't, and it looks/acts like the same thing to the end user.

    Also, another option is to use the OSX raw code for tray icons instead of the Qt stuff to work around the bug. If you are stuck on old versions of Qt maybe this is an option for you to just #ifdef some mac specific tray icon code. Not ideal but an easy solution.

  • Lifetime Qt Champion

    I don't know, I don't work for Digia, however you can find information about the CI "here":

    But like I said, test with the 64 bit prebuilt package. Creating a minimal compilable example that reproduce the behavior will help creating a patch.

Log in to reply