Bug 79785

Summary: [Qt] WebKit with Qt5 hangs on Mac
Product: WebKit Reporter: Balazs Kelemen <kbalazs>
Component: PlatformAssignee: Caio Marcelo de Oliveira Filho <cmarcelo>
Status: RESOLVED FIXED    
Severity: Normal CC: ahf, cmarcelo, vestbo, zeno
Priority: P1 Keywords: Qt, QtTriaged
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: OS X 10.7   
Attachments:
Description Flags
Patch vestbo: review+

Description Balazs Kelemen 2012-02-28 07:00:16 PST
Either start QtTestBrowser, MiniBrowser or DumpRenderTree it hangs, the main thread is in dead lock:

#0  0x00007fff90066bca in __psynch_cvwait ()
#1  0x00007fff8caac274 in _pthread_cond_wait ()
#2  0x0000000102c5ee46 in QWaitConditionPrivate::wait ()
#3  0x0000000102c5ec5f in QWaitCondition::wait ()
#4  0x0000000102c5892e in QSemaphore::acquire ()
#5  0x0000000102d84b0d in QMetaMethod::invoke ()
#6  0x0000000102d841c8 in QMetaObject::invokeMethod ()
#7  0x00000001036e57f2 in QNetworkConfigurationManagerPrivate::updateConfigurations ()
#8  0x00000001036e3243 in qNetworkConfigurationManagerPrivate ()
#9  0x00000001036e3397 in QNetworkConfigurationManager::QNetworkConfigurationManager ()
#10 0x0000000100900a0b in WebCore::NetworkStateNotifierPrivate::NetworkStateNotifierPrivate ()
#11 0x0000000100900cae in WebCore::NetworkStateNotifier::NetworkStateNotifier ()
#12 0x0000000100770c3a in WebCore::networkStateNotifier ()
#13 0x0000000100700c87 in WebCore::Page::Page ()
#14 0x00000001000728ed in QWebPagePrivate::QWebPagePrivate ()
#15 0x000000010007b52d in QWebPage::QWebPage ()
#16 0x00000001000071db in WebCore::WebPage::WebPage ()
#17 0x0000000100008a7c in WebCore::DumpRenderTree::DumpRenderTree ()
#18 0x0000000100019690 in main ()

I use the weekly pinned hashes (7f8c9b7eaf9efcda699d4f170cb72f5c2cb71a1d) on OS X Lion.
Simple examples do work with my Qt5 build.
Comment 1 Balazs Kelemen 2012-02-28 08:55:12 PST
I have debugged it a bit further so here are my founds. 
in QNetworkConfigurationManagerPrivate::updateConfigurations there is this:

foreach (QBearerEngine* engine, enginesToInitialize) {
    QMetaObject::invokeMethod(engine, "initialize", Qt::BlockingQueuedConnection);
}

This waits until the engine initializing on the bearer thread, but that thread gets blocked during this initialization:

#0  0x00007fff90066bf2 in __psynch_mutexwait ()
#1  0x00007fff8caa71a1 in pthread_mutex_lock ()
#2  0x00007fff8cdb4e9a in __cxa_guard_acquire ()
#3  0x0000000109324cfd in manager () at qnetworkinterface.cpp:82
#4  0x0000000109324eab in QNetworkInterface::allInterfaces () at qnetworkinterface.cpp:544
#5  0x000000010f0beeed in QGenericEngine::doRequestUpdate (this=0x110903640) at qgenericengine.cpp:199
#6  0x000000010f0beea5 in QGenericEngine::initialize (this=0x110903640) at qgenericengine.cpp:182
#7  0x000000010f0c9f25 in QGenericEngine::qt_static_metacall (_o=0x110903640, _c=QMetaObject::InvokeMetaMethod, _id=1, _a=0x7fff5fbfde60) at moc_qgenericengine.cpp:55
#8  0x000000010807248e in QMetaCallEvent::placeMetaCall (this=0x10f511950, object=0x110903640) at qobject.cpp:436

I don't know the reason of this second deadlock. Do you think I should file it into JIRA? Do you have an idea how to create an example that reproduce this? I don't see anything in WebKit that seems to be responsible. The Qt network examples do not reproduce it though.
Comment 2 Tor Arne Vestbø 2012-02-28 08:58:16 PST
Interesting. You might be able to reproduce using QNetworkConfigurationManager directly. Try a JIRA bug and see what the responsible people say, perhaps they have some hints.
Comment 3 Balazs Kelemen 2012-02-28 09:44:30 PST
Filed https://bugreports.qt-project.org/browse/QTBUG-24554
Comment 4 Balazs Kelemen 2012-04-12 06:05:24 PDT
Fixed in Qt.
Comment 5 Zeno Albisser 2012-04-12 07:13:36 PDT
Actually this issue is not really fixed in Qt.
It is a race condition in local static initialization.

Compilers on mac actually put a cxa_guard around local static initializers, unless the created type is POD.
It seems that for these cxa_guards there is only one mutex for all local statics being used process wide, instead of one mutex per definition.
This means that whenever one thread is waiting in a static initialization, for another thread to initialize another local static variable, this will lead to a deadlock.
Unfortunately such local static initializers are used in Q_GLOBAL_STATIC macro which is used frequently in Qt.
I filed a bug report about this to apple. - I hope we will see this fixed in the compiler soon.
Comment 6 Caio Marcelo de Oliveira Filho 2012-05-14 14:06:56 PDT
(In reply to comment #5)

> Unfortunately such local static initializers are used in Q_GLOBAL_STATIC macro which is used frequently in Qt.
> I filed a bug report about this to apple. - I hope we will see this fixed in the compiler soon.

Zeno, any updates on your report? Is it publicly available?
Comment 7 Caio Marcelo de Oliveira Filho 2012-05-14 20:51:01 PDT
It's broken again for Lion.

Zeno, I've added more information in the corresponding QTBUG.

My feeling is that we can make a workaround here to get WebKit moving forward, then depending on the follow up from your report to Apple: either remove the workaround when possible or try to "fix" Qt by making sure we trigger QIconvCodec's Q_GLOBAL_STATIC in the right thread. What do you think?
Comment 8 Zeno Albisser 2012-05-15 02:38:23 PDT
(In reply to comment #7)
> It's broken again for Lion.
> 
> Zeno, I've added more information in the corresponding QTBUG.
> 
> My feeling is that we can make a workaround here to get WebKit moving forward, then depending on the follow up from your report to Apple: either remove the workaround when possible or try to "fix" Qt by making sure we trigger QIconvCodec's Q_GLOBAL_STATIC in the right thread. What do you think?

The radar issue is unfortunately not visible to the public.
We can possibly come up with a workaround for this particular case. But the macro is used in several places. So even if we workaround this specific issue, we might end up having the same issue somewhere else in a week.
I see only two ways to get this issue fixed.
- Wait until the compiler is fixed. (probably not a good idea)
- Change Q_GLOBAL_STATIC macro in Qt. (i'm not sure this is actually possible)

Does anybody have a good suggestion?
Comment 9 Tor Arne Vestbø 2012-05-15 02:46:55 PDT
(In reply to comment #8)
> The radar issue is unfortunately not visible to the public.

Perhaps make a dupe here: http://openradar.appspot.com/

tor arne
Comment 10 Zeno Albisser 2012-05-15 03:07:28 PDT
(In reply to comment #9)
> (In reply to comment #8)
> > The radar issue is unfortunately not visible to the public.
> 
> Perhaps make a dupe here: http://openradar.appspot.com/
> 
> tor arne

http://openradar.appspot.com/11217150
Comment 11 Caio Marcelo de Oliveira Filho 2012-05-15 06:42:00 PDT
I'm working on a potential fix for this.
Comment 12 Caio Marcelo de Oliveira Filho 2012-05-15 08:07:23 PDT
Created attachment 141972 [details]
Patch
Comment 13 Caio Marcelo de Oliveira Filho 2012-05-15 10:59:54 PDT
Committed r117094: <http://trac.webkit.org/changeset/117094>