Bug 97258

Summary: [Qt] Certain SVG content freezes QtWebKit
Product: WebKit Reporter: Dawit A. <adawit>
Component: WebKit QtAssignee: Allan Sandfeld Jensen <allan.jensen>
Status: RESOLVED FIXED    
Severity: Major CC: allan.jensen, hausmann, krit, noam, rdieter, webkit.review.bot
Priority: P2 Keywords: Qt
Version: 528+ (Nightly build)   
Hardware: PC   
OS: Linux   
Attachments:
Description Flags
SVG content that causes freezing in QtWebKit based browsers
none
reduced SVG testcase that locks up QtWebKit
none
Patch none

Description Dawit A. 2012-09-20 13:31:05 PDT
Created attachment 164972 [details]
SVG content that causes freezing in QtWebKit based browsers

QtWebKit seems to freeze when it encounters certain SVG files. I was able to extract one of these SVG files that cause the freeze while visiting the latimes blog. I have attached an excerpt I created from the SVG file. If you attempt to open the attached HTML file with any QtWebKit based browser including testing app, QtTestBrowser, the browser will start using 50% of your CPU continuously and cause a freeze.
Comment 1 Simon Hausmann 2012-09-24 04:50:23 PDT
Can you break with gdb to see what's going on? Is it perhaps in a repaint loop?
Comment 2 Dawit A. 2012-10-05 14:25:46 PDT
(In reply to comment #1)
> Can you break with gdb to see what's going on? Is it perhaps in a repaint loop?

Unfortunately I cannot because I am unable to build a debug version of qtwebkit. I have a very under powered machine (Pentium D w/ 3GB RAM) at the moment and it runs out of memory when attempting to compile qtwebkit in debug mode. Once I get my new machine in the near future, I might be able to do that.
Comment 3 Allan Sandfeld Jensen 2012-10-08 02:04:56 PDT
Looks like another issue in the gesture highlighter.

ASSERTION FAILED: !rect.intersects(next)
/src/webkit/Source/WebCore/page/GestureTapHighlighter.cpp(121) : void WebCore::{anonymous}::addHighlightRect(WebCore::Path&, const LayoutRect&, const LayoutRect&, const LayoutRect&)
1   0x7f127eb15ac8 /src/webkit/WebKitBuild/Debug/lib/libWebCore.so.1(+0x280dac8) [0x7f127eb15ac8]
2   0x7f127eb164c6 /src/webkit/WebKitBuild/Debug/lib/libWebCore.so.1(+0x280e4c6) [0x7f127eb164c6]
3   0x7f127eb16674 /src/webkit/WebKitBuild/Debug/lib/libWebCore.so.1(_ZN7WebCore21GestureTapHighlighter20pathForNodeHighlightEPKNS_4NodeE+0x8b) [0x7f127eb16674]
4   0x7f128114c444 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN6WebKit22TapHighlightController9highlightEPN7WebCore4NodeE+0x66) [0x7f128114c444]
5   0x7f1281163cfa /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN6WebKit7WebPage28highlightPotentialActivationERKN7WebCore8IntPointERKNS1_7IntSizeE+0x22a) [0x7f1281163cfa]
6   0x7f12811ee76c /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN7CoreIPC18callMemberFunctionIN6WebKit7WebPageEMS2_FvRKN7WebCore8IntPointERKNS3_7IntSizeEES4_S7_EEvRKNS_10Arguments2IT1_T2_EEPT_T0_+0x6b) [0x7f12811ee76c]
7   0x7f12811eb3c8 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN7CoreIPC13handleMessageIN8Messages7WebPage28HighlightPotentialActivationEN6WebKit7WebPageEMS5_FvRKN7WebCore8IntPointERKNS6_7IntSizeEEEEvPNS_15ArgumentDecoderEPT0_T1_+0x59) [0x7f12811eb3c8]
8   0x7f12811e9432 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN6WebKit7WebPage24didReceiveWebPageMessageEPN7CoreIPC10ConnectionENS1_9MessageIDEPNS1_15ArgumentDecoderE+0x374) [0x7f12811e9432]
9   0x7f128116828c /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN6WebKit7WebPage17didReceiveMessageEPN7CoreIPC10ConnectionENS1_9MessageIDEPNS1_15ArgumentDecoderE+0x158) [0x7f128116828c]
10  0x7f128117dfd3 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN6WebKit10WebProcess17didReceiveMessageEPN7CoreIPC10ConnectionENS1_9MessageIDEPNS1_15ArgumentDecoderE+0x2b7) [0x7f128117dfd3]
11  0x7f128117b914 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN6WebKit24WebConnectionToUIProcess17didReceiveMessageEPN7CoreIPC10ConnectionENS1_9MessageIDEPNS1_15ArgumentDecoderE+0x11a) [0x7f128117b914]
12  0x7f1280ee5013 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN7CoreIPC10Connection15dispatchMessageENS_9MessageIDEPNS_15ArgumentDecoderE+0x5f) [0x7f1280ee5013]
13  0x7f1280ee5155 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN7CoreIPC10Connection15dispatchMessageERNS0_7MessageINS_15ArgumentDecoderEEE+0x13d) [0x7f1280ee5155]
14  0x7f1280ee5355 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN7CoreIPC10Connection18dispatchOneMessageEv+0xa9) [0x7f1280ee5355]
15  0x7f1280eef6eb /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN3WTF15FunctionWrapperIMN7CoreIPC10ConnectionEFvvEEclEPS2_+0x65) [0x7f1280eef6eb]
16  0x7f1280eef49c /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZN3WTF17BoundFunctionImplINS_15FunctionWrapperIMN7CoreIPC10ConnectionEFvvEEEFvPS3_EEclEv+0x32) [0x7f1280eef49c]
17  0x7f1280f85b76 /src/webkit/WebKitBuild/Debug/lib/libWebKit2.so.1(_ZNK3WTF8FunctionIFvvEEclEv+0x72) [0x7f1280f85b76]
18  0x7f127ec30a0d /src/webkit/WebKitBuild/Debug/lib/libWebCore.so.1(_ZN7WebCore7RunLoop11performWorkEv+0xbb) [0x7f127ec30a0d]
19  0x7f127ef8699c /src/webkit/WebKitBuild/Debug/lib/libWebCore.so.1(_ZN7WebCore7RunLoop11TimerObject11performWorkEv+0x1c) [0x7f127ef8699c]
20  0x7f127ef87457 /src/webkit/WebKitBuild/Debug/lib/libWebCore.so.1(+0x2c7f457) [0x7f127ef87457]
21  0x7f12754ab56e /src/qt5/qtbase/lib/libQtCore.so.5(_ZN7QObject5eventEP6QEvent+0x25e) [0x7f12754ab56e]
22  0x7f1275d2635c /src/qt5/qtbase/lib/libQtWidgets.so.5(_ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent+0xac) [0x7f1275d2635c]
23  0x7f1275d29560 /src/qt5/qtbase/lib/libQtWidgets.so.5(_ZN12QApplication6notifyEP7QObjectP6QEvent+0x260) [0x7f1275d29560]
24  0x7f12754860ee /src/qt5/qtbase/lib/libQtCore.so.5(_ZN16QCoreApplication14notifyInternalEP7QObjectP6QEvent+0x8e) [0x7f12754860ee]
25  0x7f1275487f5e /src/qt5/qtbase/lib/libQtCore.so.5(_ZN23QCoreApplicationPrivate16sendPostedEventsEP7QObjectiP11QThreadData+0x22e) [0x7f1275487f5e]
26  0x7f12754cd543 /src/qt5/qtbase/lib/libQtCore.so.5(+0x241543) [0x7f12754cd543]
27  0x7f1276c0d655 /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x135) [0x7f1276c0d655]
28  0x7f1276c0d988 /lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x4a988) [0x7f1276c0d988]
29  0x7f1276c0da44 /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_iteration+0x34) [0x7f1276c0da44]
30  0x7f12754cd6cc /src/qt5/qtbase/lib/libQtCore.so.5(_ZN20QEventDispatcherGlib13processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE+0x5c) [0x7f12754cd6cc]
31  0x7f1275484fab /src/qt5/qtbase/lib/libQtCore.so.5(_ZN10QEventLoop4execE6QFlagsINS_17ProcessEventsFlagEE+0x11b) [0x7f1275484fab]
Comment 4 Allan Sandfeld Jensen 2012-10-08 02:08:04 PDT
The backtrace was from MiniBrowser in touch mode. The MiniBrowser in desktop mode or the QtTestBrowser neither crashes nor uses any significant CPU here.
Comment 5 Allan Sandfeld Jensen 2012-10-08 02:11:38 PDT
On closer inspection, this is not from the test-case either. This is a regression caused when activating the link to the test-case.

(In reply to comment #3)
> Looks like another issue in the gesture highlighter.
> 
> ASSERTION FAILED: !rect.intersects(next)
Comment 6 Allan Sandfeld Jensen 2012-10-08 06:45:53 PDT
I managed to reproduce it using Qt4 and QtWebKit 2.3.

The nearest common path of the backtraces seems to be:

#9  0x00007ffff0f60f64 in QPainterPathStroker::createStroke (this=<optimized out>, path=...) at painting/qpainterpath.cpp:2541
#10 0x00007ffff593e583 in WebCore::Path::strokeBoundingRect (this=0x7fff9c09f2e0, applier=0x7fffffffaf40) at /src/qtwebkit-23/Source/WebCore/platform/graphics/qt/PathQt.cpp:172
#11 0x00007ffff5a7c61c in WebCore::RenderSVGShape::calculateStrokeBoundingBox (this=0x7fff9c069a18) at /src/qtwebkit-23/Source/WebCore/rendering/svg/RenderSVGShape.cpp:398
#12 0x00007ffff5a7ac39 in WebCore::RenderSVGShape::updateShapeFromElement (this=0x7fff9c069a18) at /src/qtwebkit-23/Source/WebCore/rendering/svg/RenderSVGShape.cpp:77
#13 0x00007ffff5a77ea1 in WebCore::RenderSVGPath::updateShapeFromElement (this=0x7fff9c069a18) at /src/qtwebkit-23/Source/WebCore/rendering/svg/RenderSVGPath.cpp:50
#14 0x00007ffff5a7b1c7 in WebCore::RenderSVGShape::layout (this=0x7fff9c069a18) at /src/qtwebkit-23/Source/WebCore/rendering/svg/RenderSVGShape.cpp:153
#15 0x00007ffff5ab7634 in WebCore::SVGRenderSupport::layoutChildren (start=0x90d2f8, selfNeedsLayout=true)
    at /src/qtwebkit-23/Source/WebCore/rendering/svg/SVGRenderSupport.cpp:243
#16 0x00007ffff5aa4e4f in WebCore::RenderSVGRoot::layout (this=0x90d2f8) at /src/qtwebkit-23/Source/WebCore/rendering/svg/RenderSVGRoot.cpp:238
Comment 7 Allan Sandfeld Jensen 2012-10-08 06:49:59 PDT
(In reply to comment #6)
> I managed to reproduce it using Qt4 and QtWebKit 2.3.
> 
> The nearest common path of the backtraces seems to be:
> 

And all the functions I interrupt are in painting/qstroker.cpp

So it seems to be a problem in Qt4 QStroker, that has been solved in Qt5. Unless this is a bug that has been fixed in the last couple of weeks in WebKit and therefore doesn't show up in trunk but only in the QtWebKit 2.3 branch (which is currently merged up to 18/9).
Comment 8 Dawit A. 2012-10-08 22:45:00 PDT
(In reply to comment #7)
> (In reply to comment #6)
> > I managed to reproduce it using Qt4 and QtWebKit 2.3.
> > 
> > The nearest common path of the backtraces seems to be:
> > 
> 
> And all the functions I interrupt are in painting/qstroker.cpp
> 
> So it seems to be a problem in Qt4 QStroker, that has been solved in Qt5. Unless this is a bug that has been fixed in the last couple of weeks in WebKit and therefore doesn't show up in trunk but only in the QtWebKit 2.3 branch (which is currently merged up to 18/9).

I do not think so. I think we have an infinite loop problem somewhere in webkit's SVG related code. I just am not sure where, but I can state definitively that I can reproduce the problem with both the 2.2 and 2.3 branches. 

The reason I think the issue is in QtWebKit is because I can view the SVG file in the example svgviewer provided in Qt examples folder just fine after removing the HTML related tags from the testcase file.

Also I have no problem viewing the testcase in Chromium (v22.0.1229.79 (158531)).
Comment 9 Dawit A. 2012-10-11 10:47:49 PDT
I found the actual cause that freezes QtWebKit displaying certain SVG files. It happens when the SVG file contains <path> element whose style property contains "stroke-width: 0px;". If you set the value of "stroke-width" to 1px or higher, the lock up does not happen. Hence, the value of "stroke-width" being set to 0px is seems to be causing an infinite loop somewhere in QtWebKit's code path.

I have attached a further reduced testcase to demonstrate the problem.
Comment 10 Dawit A. 2012-10-11 10:48:41 PDT
Created attachment 168255 [details]
reduced SVG testcase that locks up QtWebKit
Comment 11 Allan Sandfeld Jensen 2012-10-16 07:56:35 PDT
The test-case reproduces the bug for me using WebKit trunk, but only in release build. In debug build, it terminates just fine for some reason.

Using gdb stepping, I have been able to determine that the loop we get stuck in is in painting/qstriker.cpp inside Qt. In the function QDashStroker::processCurrentSubpath(), and the loop starting with 
        // Dash away...
        while (!done)

Done apparently never become true. Though I am still unsure why not.
Comment 12 Allan Sandfeld Jensen 2012-10-16 09:07:33 PDT
Created attachment 168957 [details]
Patch
Comment 13 Allan Sandfeld Jensen 2012-10-16 09:08:37 PDT
I have reported the Qt side of the bug in 
https://bugreports.qt-project.org/browse/QTSDK-1324

But we can avoid our side of the issue by not setting invalid dash-patterns caused by division by 0.
Comment 14 Dawit A. 2012-10-17 06:04:08 PDT
I confirm that the proposed patch fixes the freezing problem. Hopefully this will make it to the QtWebKit 2.3 branch.
Comment 15 WebKit Review Bot 2012-10-17 16:12:20 PDT
Comment on attachment 168957 [details]
Patch

Clearing flags on attachment: 168957

Committed r131663: <http://trac.webkit.org/changeset/131663>
Comment 16 WebKit Review Bot 2012-10-17 16:12:24 PDT
All reviewed patches have been landed.  Closing bug.