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

Reply via email to