The past months I have been putting together my own QtWebKit-based browser (WildFox, BSD-licensed) and it's been an overall quite pleasant experience. I have noticed odd crashes however, basically right from the beginning. Yesterday I decided to take a deeper look at these crashes when it failed to repeatedly load my personal website, www.mayaposch.com.
The sequence of events is as follows: I use load()
or setUrl()
to tell the QWebView
element to load http://www.mayaposch.com, loadFinished()
returns false, indicating something went wrong during loading of the page and then the application segmentation faults.
I'm using Qt 4.8 (latest SDK), both release and debug libraries (dynamic).
The stack trace while running the debug build with gdb:
0 WTF::HashTable<WTF::RefPtr<WebCore::ResourceLoader>, std::pair<WTF::RefPtr<WebCore::ResourceLoader>, WTF::RefPtr<WebCore::SubstituteResource> >, WTF::PairFirstExtractor<std::pair<WTF::RefPtr<WebCore::ResourceLoader>, WTF::RefPtr<WebCore::SubstituteResource> > >, WTF::PtrHash<WTF::RefPtr<WebCore::ResourceLoader> >, WTF::PairHashTraits<WTF::HashTraits<WTF::RefPtr<WebCore::ResourceLoader> >, WTF::HashTraits<WTF::RefPtr<WebCore::SubstituteResource> > >, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceLoader> > >::isEmpty() const D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xbcd036e
1 WTF::HashMap<WTF::RefPtr<WebCore::ResourceLoader>, WTF::RefPtr<WebCore::SubstituteResource>, WTF::PtrHash<WTF::RefPtr<WebCore::ResourceLoader> >, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceLoader> >, WTF::HashTraits<WTF::RefPtr<WebCore::SubstituteResource> > >::isEmpty() const D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xbcc7315
2 WebCore::DocumentLoader::cancelPendingSubstituteLoad(WebCore::ResourceLoader*) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb3cbb96
3 WebCore::ResourceLoader::didCancel(WebCore::ResourceError const&) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb62277f
4 WebCore::SubresourceLoader::didCancel(WebCore::ResourceError const&) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb75859c
5 WebCore::ResourceLoader::cancel(WebCore::ResourceError const&) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb622900
6 WebCore::ResourceLoader::cancel() D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb62285a
7 WebCore::cancelAll(WTF::HashSet<WTF::RefPtr<WebCore::ResourceLoader>, WTF::PtrHash<WTF::RefPtr<WebCore::ResourceLoader> >, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceLoader> > > const&) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb3c8725
8 WebCore::DocumentLoader::stopLoadingSubresources() D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb3cbfa4
9 WebCore::DocumentLoader::stopLoading() D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb3ca9e0
10 WebCore::FrameLoader::stopAllLoaders(WebCore::ClearProvisionalItemPolicy) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2f3694
11 WebCore::FrameLoader::continueLoadAfterNavigationPolicy(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2f7d29
12 WebCore::FrameLoader::callContinueLoadAfterNavigationPolicy(void*, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2f76a1
13 WebCore::PolicyCallback::call(bool) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb56e06c
14 WebCore::PolicyChecker::continueAfterNavigationPolicy(WebCore::PolicyAction) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb56ed26
15 WebCore::FrameLoaderClientQt::callPolicyFunction(void (WebCore::PolicyChecker::*)(WebCore::PolicyAction), WebCore::PolicyAction) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb141188
16 WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(void (WebCore::PolicyChecker::*)(WebCore::PolicyAction), WebCore::NavigationAction const&, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb146959
17 WebCore::PolicyChecker::checkNavigationPolicy(WebCore::ResourceRequest const&, WebCore::DocumentLoader*, WTF::PassRefPtr<WebCore::FormState>, void (*)(void*, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool), void*) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb56e7ef
18 WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2f25e9
19 WebCore::FrameLoader::loadWithNavigationAction(WebCore::ResourceRequest const&, WebCore::NavigationAction const&, bool, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2f1fc5
20 WebCore::FrameLoader::loadURL(WebCore::KURL const&, WTF::String const&, WTF::String const&, bool, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::Event>, WTF::PassRefPtr<WebCore::FormState>) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2f17f1
21 WebCore::FrameLoader::loadFrameRequest(WebCore::FrameLoadRequest const&, bool, bool, WTF::PassRefPtr<WebCore::Event>, WTF::PassRefPtr<WebCore::FormState>, WebCore::ReferrerPolicy) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2f1086
22 WebCore::FrameLoader::urlSelected(WebCore::FrameLoadRequest const&, WTF::PassRefPtr<WebCore::Event>, bool, bool, WebCore::ReferrerPolicy, WebCore::ShouldReplaceDocumentIfJavaScriptURL) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2ece3e
23 WebCore::FrameLoader::changeLocation(WTF::PassRefPtr<WebCore::SecurityOrigin>, WebCore::KURL const&, WTF::String const&, bool, bool, bool) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb2ec9de
24 WebCore::ScheduledURLNavigation::fire(WebCore::Frame*) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xbc30de8
25 WebCore::NavigationScheduler::timerFired(WebCore::Timer<WebCore::NavigationScheduler>*) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb3cd565
26 WebCore::Timer<WebCore::NavigationScheduler>::fired() D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xbc7adb2
27 WebCore::ThreadTimers::sharedTimerFiredInternal() D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb4a84e6
28 WebCore::ThreadTimers::sharedTimerFired() D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb4a8433
29 WebCore::SharedTimerQt::timerEvent(QTimerEvent*) D:\Dev\Qt\SDK\Desktop\Qt\4.8.0\mingw\bin\QtWebKitd4.dll 0 0xb686a5a
30 QObject::event qobject.cpp 1157 0x6a22499a
31 QApplicationPrivate::notify_helper qapplication.cpp 4550 0xa4c020
32 QApplication::notify qapplication.cpp 3932 0xa49973
33 QCoreApplication::notifyInternal qcoreapplication.cpp 876 0x6a213252
34 QCoreApplication::sendEvent qcoreapplication.h 231 0x6a283f54
35 QEventDispatcherWin32::event qeventdispatcher_win.cpp 1135 0x6a23ac60
36 QApplicationPrivate::notify_helper qapplication.cpp 4550 0xa4c020
37 QApplication::notify qapplication.cpp 3932 0xa49973
38 QCoreApplication::notifyInternal qcoreapplication.cpp 876 0x6a213252
39 QCoreApplication::sendEvent qcoreapplication.h 231 0x6a283f54
40 QCoreApplicationPrivate::sendPostedEvents qcoreapplication.cpp 1500 0x6a21416d
41 qt_internal_proc qeventdispatcher_win.cpp 496 0x6a238a2f
42 USER32!IsDialogMessageW C:\Windows\syswow64\user32.dll 0 0x75a46238
43 operator+ 0 0x7113ae
44 USER32!AllowForegroundActivation C:\Windows\syswow64\user32.dll 0 0x75a468ea
45 qt_fast_timer_proc qeventdispatcher_win.cpp 428 0x6a2387c8
46 USER32!GetMessageExtraInfo C:\Windows\syswow64\user32.dll 0 0x75a47d31
47 ?? 0
The fault line (disassembly) is indicated as:
0xbcd036e <+0x0006> mov 0xc(%eax),%eax
Is this an internal QtWebKit
fault? From the stack trace I'd say it is, but I lack the knowledge of its internals to say what is going wrong. The crashes happen most often on my personal site, but others have reported it crashing on other sites as well, including when interrupting loading (e.g. clicking a link before loading finished).
Thanks for any help you can provide.
After a discussion on #Qt @ Freenode IRC with Net147 (Jonathan Liu) it was determined that it was indeed due to a bug in webkit: https://bugs.webkit.org/show_bug.cgi?id=83565
The crash is caused by a null pointer dereference in Source/WebCore/loader/ResourceLoader.cpp in the function ResourceLoader::didCancel(). m_documentLoader->cancelPendingSubstituteLoad(this) is called without checking if m_documentLoader is null.
What I find most interesting is that my code triggered this bug while the Qt browser demo didn't. Anyone willing to figure out why this is the case is more than welcome to :)