JDK-8184448 : Crash while loading gif images with more frames
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: 8u151,9.0.1,10
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2017-07-14
  • Updated: 2017-09-11
  • Resolved: 2017-08-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10 JDK 8 JDK 9
10Fixed 8u151Fixed 9.0.1Fixed
Related Reports
Relates :  
Description
WebView crashes while browsing wikipedia page which has gif images.


Current thread (0x00007faa7c803000):  JavaThread "JavaFX Application Thread" [_thread_in_native, id=1295, stack(0x00007fff5e1f4000,0x00007fff5e9f4000)]

Stack: [0x00007fff5e1f4000,0x00007fff5e9f4000],  sp=0x00007fff5e9ec670,  free space=8161k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libjfxwebkit.dylib+0xb2d9c4]  WebCore::ImageDecoder::frameIsCompleteAtIndex(unsigned long) const+0x14
C  [libjfxwebkit.dylib+0x719566]  WebCore::ImageFrameCache::setFrameMetadataAtIndex(unsigned long, WebCore::SubsamplingLevel, std::optional<WebCore::IntSize> const&)+0x46
C  [libjfxwebkit.dylib+0x71a03c]  WebCore::ImageFrameCache::frameAtIndexCacheIfNeeded(unsigned long, WebCore::ImageFrame::Caching, std::optional<WebCore::SubsamplingLevel> const&, std::optional<WebCore::IntSize> const&)+0xcc
C  [libjfxwebkit.dylib+0x71a68b]  WebCore::ImageFrameCache::frameDurationAtIndex(unsigned long)+0x2b
C  [libjfxwebkit.dylib+0x6e4e49]  WebCore::BitmapImage::internalStartAnimation()+0x1a9
C  [libjfxwebkit.dylib+0x6e4a70]  WebCore::BitmapImage::draw(WebCore::GraphicsContext&, WebCore::FloatRect const&, WebCore::FloatRect const&, WebCore::CompositeOperator, WebCore::BlendMode, WebCore::ImageOrientationDescription)+0x80
C  [libjfxwebkit.dylib+0x70c978]  WebCore::GraphicsContext::drawImage(WebCore::Image&, WebCore::FloatRect const&, WebCore::FloatRect const&, WebCore::ImagePaintingOptions const&)+0x88
C  [libjfxwebkit.dylib+0x70ca5e]  WebCore::GraphicsContext::drawImage(WebCore::Image&, WebCore::FloatRect const&, WebCore::ImagePaintingOptions const&)+0x4e
C  [libjfxwebkit.dylib+0x86b916]  WebCore::RenderImage::paintIntoRect(WebCore::GraphicsContext&, WebCore::FloatRect const&)+0x2b6
C  [libjfxwebkit.dylib+0x86adcf]  WebCore::RenderImage::paintReplaced(WebCore::PaintInfo&, WebCore::LayoutPoint const&)+0x67f
C  [libjfxwebkit.dylib+0x8ded72]  WebCore::RenderReplaced::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&)+0x3d2
C  [libjfxwebkit.dylib+0x86b978]  WebCore::RenderImage::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&)+0x18
C  [libjfxwebkit.dylib+0x8411f7]  WebCore::RenderElement::paintAsInlineBlock(WebCore::PaintInfo&, WebCore::LayoutPoint const&)+0xa7
C  [libjfxwebkit.dylib+0x7c32e1]  WebCore::InlineElementBox::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&, WebCore::LayoutUnit, WebCore::LayoutUnit)+0xe1
C  [libjfxwebkit.dylib+0x7c7fd3]  WebCore::InlineFlowBox::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&, WebCore::LayoutUnit, WebCore::LayoutUnit)+0x593
C  [libjfxwebkit.dylib+0x92f3c6]  WebCore::RootInlineBox::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&, WebCore::LayoutUnit, WebCore::LayoutUnit)+0x56
C  [libjfxwebkit.dylib+0x8b2ce0]  WebCore::RenderLineBoxList::paint(WebCore::RenderBoxModelObject*, WebCore::PaintInfo&, WebCore::LayoutPoint const&) const+0x370
C  [libjfxwebkit.dylib+0x7d89cc]  WebCore::RenderBlock::paintObject(WebCore::PaintInfo&, WebCore::LayoutPoint const&)+0x30c
C  [libjfxwebkit.dylib+0x7d7eb5]  WebCore::RenderBlock::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&)+0x135
C  [libjfxwebkit.dylib+0x7d84a3]  WebCore::RenderBlock::paintChild(WebCore::RenderBox&, WebCore::PaintInfo&, WebCore::LayoutPoint const&, WebCore::PaintInfo&, bool, WebCore::RenderBlock::PaintBlockType)+0x243
C  [libjfxwebkit.dylib+0x7d823f]  WebCore::RenderBlock::paintChildren(WebCore::PaintInfo&, WebCore::LayoutPoint const&, WebCore::PaintInfo&, bool)+0x4f
C  [libjfxwebkit.dylib+0x7d89ef]  WebCore::RenderBlock::paintObject(WebCore::PaintInfo&, WebCore::LayoutPoint const&)+0x32f
C  [libjfxwebkit.dylib+0x7d7eb5]  WebCore::RenderBlock::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&)+0x135
C  [libjfxwebkit.dylib+0x890d1d]  WebCore::RenderLayer::paintForegroundForFragmentsWithPhase(WebCore::PaintPhase, WTF::Vector<WebCore::LayerFragment, 1ul, WTF::CrashOnOverflow, 16ul> const&, WebCore::GraphicsContext&, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int, WebCore::RenderObject*)+0x1ad
C  [libjfxwebkit.dylib+0x88dfe5]  WebCore::RenderLayer::paintForegroundForFragments(WTF::Vector<WebCore::LayerFragment, 1ul, WTF::CrashOnOverflow, 16ul> const&, WebCore::GraphicsContext&, WebCore::GraphicsContext&, WebCore::LayoutRect const&, bool, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int, WebCore::RenderObject*, bool)+0x1a5
C  [libjfxwebkit.dylib+0x88a923]  WebCore::RenderLayer::paintLayerContents(WebCore::GraphicsContext&, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int)+0xbb3
C  [libjfxwebkit.dylib+0x88aa74]  WebCore::RenderLayer::paintLayerContents(WebCore::GraphicsContext&, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int)+0xd04
C  [libjfxwebkit.dylib+0x888191]  WebCore::RenderLayer::paint(WebCore::GraphicsContext&, WebCore::LayoutRect const&, WebCore::LayoutSize const&, unsigned int, WebCore::RenderObject*, unsigned int, WebCore::RenderLayer::SecurityOriginPaintPolicy)+0x111
C  [libjfxwebkit.dylib+0x62ad95]  WebCore::FrameView::paintContents(WebCore::GraphicsContext&, WebCore::IntRect const&, WebCore::Widget::SecurityOriginPaintPolicy)+0x225
C  [libjfxwebkit.dylib+0x6ad152]  WebCore::ScrollView::paint(WebCore::GraphicsContext&, WebCore::IntRect const&, WebCore::Widget::SecurityOriginPaintPolicy)+0x2b2
C  [libjfxwebkit.dylib+0xb1d810]  WebCore::WebPage::paint(_jobject*, int, int, int, int)+0x150
J 3407  com.sun.webkit.WebPage.twkUpdateContent(JLcom/sun/webkit/graphics/WCRenderQueue;IIII)V javafx.web@9 (0 bytes) @ 0x0000000114e10d96 [0x0000000114e10cc0+0x00000000000000d6]
j  com.sun.webkit.WebPage.updateDirty(Lcom/sun/webkit/graphics/WCRectangle;)V+218 javafx.web@9
j  com.sun.webkit.WebPage.updateContent(Lcom/sun/webkit/graphics/WCRectangle;)V+48 javafx.web@9
J 3524 c1 com.sun.javafx.sg.prism.web.NGWebView.update()V javafx.web@9 (72 bytes) @ 0x000000010de5a224 [0x000000010de59980+0x00000000000008a4]
j  javafx.scene.web.WebView.handleStagePulse()V+40 javafx.web@9
j  javafx.scene.web.WebView.lambda$new$0()V+1 javafx.web@9
j  javafx.scene.web.WebView$$Lambda$214.pulse()V+4 javafx.web@9
J 2551 c1 com.sun.javafx.tk.Toolkit$$Lambda$235.run()Ljava/lang/Object; javafx.graphics@9 (8 bytes) @ 0x000000010dc6a19c [0x000000010dc6a060+0x000000000000013c]
v  ~StubRoutines::call_stub
V  [libjvm.dylib+0x3a28cd]  JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, Thread*)+0x2b5
V  [libjvm.dylib+0x412323]  JVM_DoPrivileged+0x466
J 2209  java.security.AccessController.doPrivileged(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object; java.base@9 (0 bytes) @ 0x0000000114d6df15 [0x0000000114d6de40+0x00000000000000d5]
J 2441 c1 com.sun.javafx.tk.Toolkit.runPulse(Lcom/sun/javafx/tk/TKPulseListener;Ljava/security/AccessControlContext;)V javafx.graphics@9 (26 bytes) @ 0x000000010dc2df04 [0x000000010dc2db20+0x00000000000003e4]
j  com.sun.javafx.tk.Toolkit.firePulse()V+129 javafx.graphics@9
J 3397 c1 com.sun.javafx.tk.quantum.QuantumToolkit.pulse(Z)V javafx.graphics@9 (152 bytes) @ 0x000000010de1284c [0x000000010de12220+0x000000000000062c]
J 3182 c1 com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$75.run()V javafx.graphics@9 (8 bytes) @ 0x000000010dd94834 [0x000000010dd94580+0x00000000000002b4]
J 2814 c1 com.sun.glass.ui.InvokeLaterDispatcher$Future.run()V javafx.graphics@9 (91 bytes) @ 0x000000010dcc8e0c [0x000000010dcc8d00+0x000000000000010c]
v  ~StubRoutines::call_stub
V  [libjvm.dylib+0x3a28cd]  JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, Thread*)+0x2b5
V  [libjvm.dylib+0x3d5255]  jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)+0x2b4
V  [libjvm.dylib+0x3d87de]  jni_CallVoidMethod+0x197
C  [libglass.dylib+0x50fb]  -[GlassRunnable run]+0x6b
C  [Foundation+0x76fde]  __NSThreadPerformPerform+0x117
C  [CoreFoundation+0xaa7e1]  __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+0x11
C  [CoreFoundation+0x89f1c]  __CFRunLoopDoSources0+0x22c
C  [CoreFoundation+0x8943f]  __CFRunLoopRun+0x39f
C  [CoreFoundation+0x88e38]  CFRunLoopRunSpecific+0x128
C  [HIToolbox+0x30935]  RunCurrentEventLoopInMode+0xeb
C  [HIToolbox+0x3076f]  ReceiveNextEventCommon+0x1b0
C  [HIToolbox+0x305af]  _BlockUntilNextEventMatchingListInModeWithFilter+0x47
C  [AppKit+0x48df6]  _DPSNextEvent+0x42b
C  [AppKit+0x48226]  -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:]+0x1c6
C  [AppKit+0x3cd80]  -[NSApplication run]+0x2aa
C  [libglass.dylib+0x716b]  -[GlassApplication runLoop:]+0x78b
C  [Foundation+0x76fde]  __NSThreadPerformPerform+0x117
C  [CoreFoundation+0xaa7e1]  __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+0x11
C  [CoreFoundation+0x89f1c]  __CFRunLoopDoSources0+0x22c
C  [CoreFoundation+0x8943f]  __CFRunLoopRun+0x39f
C  [CoreFoundation+0x88e38]  CFRunLoopRunSpecific+0x128
C  [java+0x6b2e]  CreateExecutionEnvironment+0x35c
C  [java+0x2c65]  JLI_Launch+0x5a9
C  [java+0x1b62]  main+0x186
C  [java+0x19d4]  start+0x34
C  0x0000000000000007
Comments
changeset: 542116615e59 user: arajkumar date: Mon Aug 07 11:30:54 2017 +0530 description: 8184448: Crash while loading gif images with more frames Reviewed-by: ghb, kcr, mbilla URL: http://hg.openjdk.java.net/openjfx/10-dev/rt/rev/542116615e59
07-08-2017

Thanks .. +1 with below nit (another webrev not needed for me, unless other reviewers have any concern) Either change "@param index" to "@param idx" OR change parameter name from "idx" to "index". * @param index frame index + */ + protected abstract WCImageFrame getFrame(int idx);
07-08-2017

Thanks [~mbilla]. Hope http://cr.openjdk.java.net/~arajkumar/8184448/webrev.03 will address the concerns.
07-08-2017

Thanks. Incorporated [~mbilla]'s review comments in http://cr.openjdk.java.net/~arajkumar/8184448/webrev.02 . I have also added proper copyrights header in addition to his comments.
07-08-2017

nit: 1. Can you follow uniform pattern for below 2 variants (though both are same) : final int[] size = THREAD_LOCAL_SIZE_ARRAY.get(); final int size [] = THREAD_LOCAL_SIZE_ARRAY.get(); 2. As mentioned above, please add @param description for getFrame API.
07-08-2017

looks good.. +1 with below minor points: 1) For below API description in WCImageDecoder.java, you can follow the same pattern as other APIs. /* * Returns image frame at the specified index. */ protected abstract WCImageFrame getFrame(int idx); For ex: /** * Returns image frame at the specified index. * @param idx frame index */ 2. For cpp and java files (PrismGraphicsManager.java, WCImageDecoder.java, RenderMediaControls.java, WCImageDecoder.java, WCImageFrame.java, PasteboardJava.cpp etc....) you can correct the copyright year /* 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. To /* 2 * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. As a HEADS UP, regarding image decoding, i see below significant changes in upstream for next porting. You can have a look at those. https://trac.webkit.org/changeset/213563/webkit - Asynchronous image decoding should consider the drawing size if it is smaller than the size of the image https://trac.webkit.org/changeset/213618/webkit - Enable async image decoding for large images
04-08-2017

Looks good to me. Is it possible to add Unit test as a separate JBS.
03-08-2017

Looks good to me. +1
03-08-2017

.01 + linux : 'gif.html' animates as expected (missed out providing the network proxy earlier).
02-08-2017

Thanks [~ghb] for your comments. You should see the animating gif, otherwise the problem should be addressed. I have tested in Mac and Windows and I see the gif images. Regarding replacing int[] with Dimension2D: it is a nice abstraction, but in the native we need to add more code access the width and height from Dimension2D instance. So I don't see much benefit in using that.
02-08-2017

.01 on Linux. Didn't observe the crash with 'gif.html' and content is not rendered (as it animates in Chrome / Firefox) is this expected ? Instead of managing W x H in int[] --> Dimension2D (com.sun.javafx.geom.Dimension2D) looks cleaner. I did modified your patch (Attached diff with // FIXME note) with Dimension2D LOC will be less, only disadvantage is Dimension2D is has Data time of double but this won't be a limiting factor.
02-08-2017

Major problem is missing synchronisation while accessing the state members(from both Native and Java) as explained in [1]. Also the meta data cache we had in ImageDecoderJava(m_frameInfos) returns invalid data while accessing in nonlinear fashion(WebCore asks for a metadata before calling createFrameAtIndex - a place where we cache meta data). So I have removed a native meta data cache(m_frameInfos) and all meta data request now goes to WCImageDecoderImpl.java. Also ImageFrameData class which we had introduced during new WebKit porting seems unnecessary because we can call WCImageFrame::getSize to get the size of a frame. [1] https://bugs.openjdk.java.net/browse/JDK-8184448?focusedCommentId=14101368&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14101368
02-08-2017

Can you add a brief explanation about your fix to understand better ..
01-08-2017

http://cr.openjdk.java.net/~arajkumar/8184448/webrev.01
28-07-2017

Preliminary fix : http://cr.openjdk.java.net/~arajkumar/8184448/webrev (only {drt, sanity}tested on OSX)
28-07-2017

Looks like a synchronisation issue. New WebKit uses threaded decoding using WorkQueue primitives, createFrameImageAtIndex(from FX App thread & WorkQueue) and rest of the methods(FX App thread) may be called concurrently. Unlike other WebKit ports, we have lots of state members access during createFrameImageAtIndex. Planning to try with Locks to add synchronisation per decoder instance.
14-07-2017

Attached the reduced test to reproduce the issue.
14-07-2017