I have just filed bugs on the two problems discovered here: QTBUG-86874 QTBUG-86875
I have not found a way to get menu item relocation in the global menubar to work properly on macOS without triggering a crash on quit as a side effect, and I think I’m going to give up on it for the time being. Oh well. Cheers, -B. Benjamin C. Haller Messer Lab Cornell University > On Sep 23, 2020, at 12:40 PM, Ben Haller via Interest > <interest@qt-project.org> wrote: > > Sorry for all the emails; this is proving to be quite a difficult problem and > I’m really hoping somebody has insight into it. > > This code also produces the same crash as the static QFont usage I posted in > my previous email, and this code seems very clearly innocent: > > ———————— > > QFont tickFont; > #ifdef __APPLE__ > tickFont.setPointSize(9); > #else > tickFont.setPointSize(7); > #endif > painter.setFont(tickFont); > > ———————— > > So now I’m starting to think this may actually be a Qt bug, perhaps related > to caching of fonts internally in QOpenGLWidget. > > But here’s the interesting bit: there is one other change in my app that is > also causal. I’m trying to get my app on macOS to stay running after the > last window has closed, and to get the global menu bar to work properly in > that mode of operation, I need to keep my main window alive after it’s closed > (see the previous discussion thread on Qt-Interest). To achieve that, I’m > commenting out the call to: > > setAttribute(Qt::WA_DeleteOnClose); > > in my main window’s initialization. With that call commented out, I can > close the window, the global menubar remains correct because the main window > is still alive in the background, BUT the app crashes on quit due to the font > issue above. With that setAttribute() call in place (not commented out), I > can close the window, the app does not crash on quit, BUT the global menubar > is screwed up because there’s no main window (see previous thread). > > My closeEvent() just calls event->accept(); and returns. With the > setAttribute() call commented out, the window does not get deleted any more, > it just closes (I have a qDebug() in its destructor to confirm that). But > then quitting crashes. Putting the setAttribute() call back in fixes the > crash; OR, commenting out the use of QFont in my QOpenGLWidget subclass fixes > the crash. > > Anybody know what’s going on, and how I might fix it or work around it? I > need to change the font in my widget, of course; and I seem to need to avoid > deleting my main window, in order to keep the global menubar working when the > last main window closes. So I’m stuck. > > Cheers, > -B. > > Benjamin C. Haller > Messer Lab > Cornell University > > >> On Sep 23, 2020, at 12:04 PM, Ben Haller via Interest >> <interest@qt-project.org> wrote: >> >> Hi all. I’m starting a new thread since the focal question has completely >> changed. I’ve tracked down the cause of the crash that I discussed in the >> previous thread, to a specific bit of code: >> >> ———————— >> >> static QFont *tickFont = nullptr; >> >> if (!tickFont) >> { >> tickFont = new QFont(); >> tickFont->setPointSize(9); >> } >> painter.setFont(*tickFont); >> >> ———————— >> >> I do this inside a QOpenGLWidget subclass, in my paintGL() override. If I >> comment this code out, no more crash on quit. I figured this out because >> the backtrace for my crash seemed to involve private font cache teardown in >> QApplication, so I figured maybe I was doing something naughty involved >> QFonts, so I commented out every usage of QFont in my app, and then started >> uncommenting them one by one; when I uncommented this one, it crashes on >> quit. (I got AddressSanitizer working, but it didn’t provide any additional >> info; I’m still working on getting Valgrind working on macOS 10.15.) >> >> So. What is wrong with the pattern above? I’m surprised that this crashes. >> My intent is simply to keep this QFont instance permanently allocated, so >> that whatever overhead is associated with making a new one doesn’t occur >> each time my view repaints (which happens at ~60Hz, ideally). That is >> perhaps premature optimization, which is the root of all evil, I realize. >> But I want to understand *why* this pattern is bad, and what I might do >> instead, if the font creation were to indeed be a bottleneck. Obviously >> there’s something about memory management in Qt that I don’t understand, >> because I don’t see anything wrong with this code! :-> Thanks for any help. >> >> Cheers, >> -B. >> >> Benjamin C. Haller >> Messer Lab >> Cornell University >> >> >>> On Sep 23, 2020, at 7:50 AM, Ben Haller via Interest >>> <interest@qt-project.org> wrote: >>> >>> Hi all. I’m trying to figure out what appears to be a double dealloc >>> problem of some sort. I’m sure the actual bug is in my code (I’m trying to >>> get a window with complex subsidiary windows, etc., to disassemble and free >>> the things it owns, without freeing itself), but the backtrace at the point >>> that the crash happens doesn’t have any of my code in it at all. I’ve >>> appended the full backtrace below my signature, in case it is informative; >>> maybe somebody has seen this pattern before and knows what I’m likely to be >>> doing wrong. My code does not use QFontCache or QScopedPointer at all, so >>> it’s hard to guess where my bug might be. >>> >>> My question, though, is bigger: how would folks here recommend debugging a >>> double dealloc in a Qt-based app, running under Qt Creator? I’m coming >>> from the Cocoa/Xcode world, and in that world there’s a very nice tool >>> called NSZombie: you set a flag, and then whenever an object would be >>> deallocated, it instead turns into an NSZombie object that produces nice >>> console logs if anybody ever tries to use that memory as an object again. >>> But that’s for NSObject. Is there something similar in the Qt world, such >>> that I could get a console log or a break in the debugger at the point >>> where a C++/Qt object that has been dealloced gets touched again? Or if >>> not, how would you recommend approaching this? Thanks for any help. >>> >>> Cheers, >>> -B. >>> >>> Benjamin C. Haller >>> Messer Lab >>> Cornell University >>> >>> >>> 1 QScopedPointer<QObjectData, >>> QScopedPointerDeleter<QObjectData>>::operator->() const >>> >>> >>> qscopedpointer.h 118 >>> 0x10201b594 >>> 2 decltype(fp.operator->()) qGetPtrHelper<QScopedPointer<QObjectData, >>> QScopedPointerDeleter<QObjectData>> const>(QScopedPointer<QObjectData, >>> QScopedPointerDeleter<QObjectData>> const&) >>> >>> qglobal.h 1133 0x10201b594 >>> 3 QObject::d_func() const >>> >>> >>> qobject.h >>> 132 0x10201b594 >>> 4 QObject::thread() const >>> >>> >>> qobject.cpp >>> 1512 0x10201b594 >>> 5 QOpenGLVertexArrayObjectPrivate::destroy() >>> >>> >>> >>> qopenglvertexarrayobject.cpp 212 0x101b21481 >>> 6 QOpenGLVertexArrayObject::destroy() >>> >>> >>> >>> qopenglvertexarrayobject.cpp 424 0x101b217cc >>> 7 QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() >>> >>> >>> >>> qopenglvertexarrayobject.cpp 392 0x101b217c3 >>> 8 QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() >>> >>> >>> >>> qopenglvertexarrayobject.cpp 391 0x101b217b9 >>> 9 QOpenGLTextureGlyphCache::~QOpenGLTextureGlyphCache() >>> >>> >>> >>> qopengltextureglyphcache.cpp 93 0x101b1cacd >>> 10 QOpenGLTextureGlyphCache::~QOpenGLTextureGlyphCache() >>> >>> >>> >>> qopengltextureglyphcache.cpp 88 0x101b1cbce >>> 11 QOpenGLTextureGlyphCache::~QOpenGLTextureGlyphCache() >>> >>> >>> >>> qopengltextureglyphcache.cpp 88 0x101b1cbc9 >>> 12 >>> QExplicitlySharedDataPointer<QFontEngineGlyphCache>::~QExplicitlySharedDataPointer() >>> >>> >>> qshareddata.h >>> 184 0x101883c92 >>> 13 >>> QExplicitlySharedDataPointer<QFontEngineGlyphCache>::~QExplicitlySharedDataPointer() >>> >>> >>> qshareddata.h >>> 184 0x101883c74 >>> 14 QFontEngine::GlyphCacheEntry::~GlyphCacheEntry() >>> >>> >>> qfontengine.cpp >>> 1570 0x101883c74 >>> 15 QFontEngine::GlyphCacheEntry::~GlyphCacheEntry() >>> >>> >>> qfontengine.cpp >>> 1569 0x101883c74 >>> 16 void >>> std::allocator_traits<std::allocator<std::__list_node<QFontEngine::GlyphCacheEntry, >>> void >>> *>>>::__destroy<QFontEngine::GlyphCacheEntry>(std::integral_constant<bool, >>> false>, std::allocator<std::__list_node<QFontEngine::GlyphCacheEntry, void >>> *>>&, QFontEngine::GlyphCacheEntry *) memory >>> 1732 0x101883c74 >>> 17 void >>> std::allocator_traits<std::allocator<std::__list_node<QFontEngine::GlyphCacheEntry, >>> void >>> *>>>::destroy<QFontEngine::GlyphCacheEntry>(std::allocator<std::__list_node<QFontEngine::GlyphCacheEntry, >>> void *>>&, QFontEngine::GlyphCacheEntry *) >>> memory 1595 0x101883c74 >>> 18 std::__list_imp<QFontEngine::GlyphCacheEntry, >>> std::allocator<QFontEngine::GlyphCacheEntry>>::clear() >>> >>> >>> list 733 0x101883c74 >>> 19 std::__list_imp<QFontEngine::GlyphCacheEntry, >>> std::allocator<QFontEngine::GlyphCacheEntry>>::~__list_imp() >>> >>> >>> list 712 0x101883c24 >>> 20 std::list<QFontEngine::GlyphCacheEntry>::~list() >>> >>> >>> list >>> 805 0x101883c24 >>> 21 std::list<QFontEngine::GlyphCacheEntry>::~list() >>> >>> >>> list >>> 805 0x101883c24 >>> 22 QHashNode<void const *, >>> std::list<QFontEngine::GlyphCacheEntry>>::~QHashNode() >>> >>> >>> qhash.h 147 >>> 0x101883c24 >>> 23 QHashNode<void const *, >>> std::list<QFontEngine::GlyphCacheEntry>>::~QHashNode() >>> >>> >>> qhash.h 147 >>> 0x101883c24 >>> 24 QHash<void const *, >>> std::list<QFontEngine::GlyphCacheEntry>>::deleteNode2(QHashData::Node *) >>> >>> >>> qhash.h >>> 563 0x101883c24 >>> 25 QHashData::free_helper(void ( *)(QHashData::Node *)) >>> >>> >>> qhash.cpp >>> 572 0x101e5db39 >>> 26 QHash<void const *, >>> std::list<QFontEngine::GlyphCacheEntry>>::freeData(QHashData *) >>> >>> >>> qhash.h >>> 603 0x10187a47b >>> 27 QHash<void const *, std::list<QFontEngine::GlyphCacheEntry>>::~QHash() >>> >>> >>> qhash.h >>> 250 0x10187a46f >>> 28 QHash<void const *, std::list<QFontEngine::GlyphCacheEntry>>::~QHash() >>> >>> >>> qhash.h >>> 250 0x10187a44f >>> 29 QFontEngine::~QFontEngine() >>> >>> >>> qfontengine.cpp >>> 277 0x10187a44f >>> 30 QCoreTextFontEngine::~QCoreTextFontEngine() >>> >>> >>> >>> qfontengine_coretext.mm 215 0x105b7cf8e >>> 31 QCoreTextFontEngine::~QCoreTextFontEngine() >>> >>> >>> >>> qfontengine_coretext.mm 215 0x105b7cf89 >>> 32 QFontEngineMulti::~QFontEngineMulti() >>> >>> >>> qfontengine.cpp >>> 1782 0x101880039 >>> 33 QFontEngineMulti::~QFontEngineMulti() >>> >>> >>> qfontengine.cpp >>> 1778 0x10188012e >>> 34 QFontEngineMulti::~QFontEngineMulti() >>> >>> >>> qfontengine.cpp >>> 1778 0x101880129 >>> 35 QFontCache::clear() >>> >>> >>> qfont.cpp >>> 2861 0x1018762eb >>> 36 QFontCache::~QFontCache() >>> >>> >>> qfont.cpp >>> 2817 0x10187603c >>> 37 QFontCache::~QFontCache() >>> >>> >>> qfont.cpp >>> 2816 0x1018763ee >>> 38 QFontCache::~QFontCache() >>> >>> >>> qfont.cpp >>> 2816 0x1018763e9 >>> 39 QThreadStorageData::set(void *) >>> >>> >>> qthreadstorage.cpp >>> 162 0x101e25777 >>> 40 QGuiApplicationPrivate::~QGuiApplicationPrivate() >>> >>> >>> >>> qguiapplication.cpp 1694 0x1017ca490 >>> 41 QApplicationPrivate::~QApplicationPrivate() >>> >>> >>> qapplication.cpp >>> 184 0x10116f81e >>> 42 QApplicationPrivate::~QApplicationPrivate() >>> >>> >>> qapplication.cpp >>> 184 0x10116f819 >>> 43 QScopedPointerDeleter<QObjectData>::cleanup(QObjectData *) >>> >>> >>> qscopedpointer.h >>> 60 0x10201c06c >>> 44 QScopedPointer<QObjectData, >>> QScopedPointerDeleter<QObjectData>>::~QScopedPointer() >>> >>> >>> qscopedpointer.h 107 >>> 0x10201c061 >>> 45 QScopedPointer<QObjectData, >>> QScopedPointerDeleter<QObjectData>>::~QScopedPointer() >>> >>> >>> qscopedpointer.h 105 >>> 0x10201c05d >>> 46 QObject::~QObject() >>> >>> >>> qobject.cpp >>> 1119 0x10201c05d >>> 47 QApplication::~QApplication() >>> >>> >>> qapplication.cpp >>> 837 0x101171b3d >>> 48 main >>> >>> >>> main.cpp >>> 246 0x100012256 >>> 49 start >>> >>> >>> (x86_64) >>> /usr/lib/system/libdyld.dylib 0x7fff6b461cc9 >>> >>> _______________________________________________ >>> Interest mailing list >>> Interest@qt-project.org >>> https://lists.qt-project.org/listinfo/interest >> >> _______________________________________________ >> Interest mailing list >> Interest@qt-project.org >> https://lists.qt-project.org/listinfo/interest > > _______________________________________________ > Interest mailing list > Interest@qt-project.org > https://lists.qt-project.org/listinfo/interest _______________________________________________ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest