JDK-6300721 : Creating Animated GIF images repeatedly with different image frames crashes the VM
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-07-22
  • Updated: 2011-01-19
  • Resolved: 2005-12-05
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.
6 b63Fixed
Related Reports
Relates :  
Relates :  
I am running an application which creates animated gif images from different set of image frames in a loop. This application uses set of transparent gif frames, opaque gif frames, png image frames, jpg etc in the given order. Exactly during the third iteration, the VM crashes. That is, when creating the gif image from set of PNG image frames. 

This is reproducible consistantly across WinXP and Solaris10-JDS with Mustang-b43. 

I have attached a sample test. Untar it and run the sample test. It will automatically pick-up image files from different folders available in the same directory and tries to create the animated gif. Click 'Next' button repeatedly. You would notice a VM crash during the third iteration. 

Here is the crash info:
# An unexpected error has been detected by HotSpot Virtual Machine:
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x008afa59, pid=1348, tid=3940
# Java VM: Java HotSpot(TM) Client VM (1.6.0-ea-b43 mixed mode)
# Problematic frame:
# j  sun.java2d.pipe.DrawImage.scaleSurfaceData(Lsun/java2d/SunGraphics2D;Lsun/java2d/pipe/Region;Lsun/java2d/SurfaceData;Lsun/java2d/SurfaceData;Lsun/java2d/loops/SurfaceType;Lsun/java2d/loops/SurfaceType;IIIIDDDD)Z+18

---------------  T H R E A D  ---------------

Current thread (0x0acbb800):  JavaThread "AWT-EventQueue-0" [_thread_in_Java, id=3940]

siginfo: ExceptionCode=0xc0000005, reading address 0xff070843

EAX=0xff070707, EBX=0x00000009, ECX=0x02e83ca8, EDX=0x30800001
ESP=0x0af9f2dc, EBP=0x0af9f304, ESI=0x06c0c57a, EDI=0x0af9f35c
EIP=0x008afa59, EFLAGS=0x00010246

Top of Stack: (sp=0x0af9f2dc)
0x0af9f2dc:   008a2d25 02e83ca8 0af9f2e4 06c0c57a
0x0af9f2ec:   0af9f35c 06c0cdb8 00000000 06c0c5c8
0x0af9f2fc:   00000000 0af9f314 0af9f380 008a2e2d
0x0af9f30c:   00000000 02e28278 00000000 40594000
0x0af9f31c:   00000000 40594000 00000000 3ff00000
0x0af9f32c:   00000000 3ff00000 00000089 0000008a
0x0af9f33c:   00000000 00000000 02e2ada0 ff070707
0x0af9f34c:   02f7cac0 02e83ca8 0293a880 0293a760 

Instructions: (pc=0x008afa59)
0x008afa49:   00 3b 01 8d 74 24 04 89 75 f8 ff 63 50 8b 41 04
0x008afa59:   8b 9c 98 18 01 00 00 8d 74 24 04 89 75 f8 ff 63 

Stack: [0x0af60000,0x0afa0000),  sp=0x0af9f2dc,  free space=252k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
j  sun.java2d.pipe.DrawImage.scaleSurfaceData(Lsun/java2d/SunGraphics2D;Lsun/java2d/pipe/Region;Lsun/java2d/SurfaceData;Lsun/java2d/SurfaceData;Lsun/java2d/loops/SurfaceType;Lsun/java2d/loops/SurfaceType;IIIIDDDD)Z+18
j  sun.java2d.pipe.DrawImage.renderImageScale(Lsun/java2d/SunGraphics2D;Ljava/awt/Image;Ljava/awt/Color;IIIIIDDDD)Z+95
j  sun.java2d.pipe.DrawImage.scaleImage(Lsun/java2d/SunGraphics2D;Ljava/awt/Image;IIIILjava/awt/Color;)Z+89
j  sun.java2d.pipe.DrawImage.scaleImage(Lsun/java2d/SunGraphics2D;Ljava/awt/Image;IIIILjava/awt/Color;Ljava/awt/image/ImageObserver;)Z+19
j  sun.java2d.SunGraphics2D.drawImage(Ljava/awt/Image;IIIILjava/awt/Color;Ljava/awt/image/ImageObserver;)Z+72
j  sun.awt.image.ImageRepresentation.drawToBufImage(Ljava/awt/Graphics;Lsun/awt/image/ToolkitImage;IIIILjava/awt/Color;Ljava/awt/image/ImageObserver;)Z+156
j  sun.java2d.pipe.DrawImage.scaleImage(Lsun/java2d/SunGraphics2D;Ljava/awt/Image;IIIILjava/awt/Color;Ljava/awt/image/ImageObserver;)Z+64
j  sun.java2d.pipe.ValidatePipe.scaleImage(Lsun/java2d/SunGraphics2D;Ljava/awt/Image;IIIILjava/awt/Color;Ljava/awt/image/ImageObserver;)Z+25
j  sun.java2d.SunGraphics2D.drawImage(Ljava/awt/Image;IIIILjava/awt/Color;Ljava/awt/image/ImageObserver;)Z+72
j  sun.java2d.SunGraphics2D.drawImage(Ljava/awt/Image;IIIILjava/awt/image/ImageObserver;)Z+11
j  AnimatedGIFTest$ImageCanvas.paint(Ljava/awt/Graphics;)V+28
j  java.awt.Canvas.update(Ljava/awt/Graphics;)V+16
J  sun.awt.RepaintArea.paint(Ljava/lang/Object;Z)V
j  sun.awt.windows.WComponentPeer.handleEvent(Ljava/awt/AWTEvent;)V+63
j  java.awt.Component.dispatchEventImpl(Ljava/awt/AWTEvent;)V+825
j  java.awt.Component.dispatchEvent(Ljava/awt/AWTEvent;)V+2
j  java.awt.EventQueue.dispatchEvent(Ljava/awt/AWTEvent;)V+46
J  java.awt.EventDispatchThread.pumpOneEventForFilters(I)Z
j  java.awt.EventDispatchThread.pumpEventsForFilter(ILjava/awt/Conditional;Ljava/awt/EventFilter;)V+148
j  java.awt.EventDispatchThread.pumpEventsForHierarchy(ILjava/awt/Conditional;Ljava/awt/Component;)V+11
j  java.awt.EventDispatchThread.pumpEvents(ILjava/awt/Conditional;)V+4
j  java.awt.EventDispatchThread.pumpEvents(Ljava/awt/Conditional;)V+3
j  java.awt.EventDispatchThread.run()V+9
v  ~StubRoutines::call_stub

---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x0ad4eb00 JavaThread "Image Animator 3" daemon [_thread_in_vm, id=1176]
  0x00037000 JavaThread "DestroyJavaVM" [_thread_blocked, id=2400]
=>0x0acbb800 JavaThread "AWT-EventQueue-0" [_thread_in_Java, id=3940]
  0x0acb6400 JavaThread "AWT-Windows" daemon [_thread_in_native, id=2188]
  0x0ac7a000 JavaThread "AWT-Shutdown" [_thread_blocked, id=320]
  0x0aa9f500 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=2688]
  0x0aa92700 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=3516]
  0x0aa90200 JavaThread "CompilerThread0" daemon [_thread_blocked, id=4040]
  0x0aa8f300 JavaThread "Attach Listener" daemon [_thread_blocked, id=3620]
  0x0aa8e800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=3812]
  0x0aa82700 JavaThread "Finalizer" daemon [_thread_blocked, id=3800]
  0x0aa81200 JavaThread "Reference Handler" daemon [_thread_blocked, id=3380]

Other Threads:
  0x0aa7cc00 VMThread [id=3788]
  0x0ac78100 WatcherThread [id=3688]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

 def new generation   total 576K, used 138K [0x02920000, 0x029c0000, 0x02e00000)
  eden space 512K,  21% used [0x02920000, 0x0293b9f8, 0x029a0000)
  from space 64K,  43% used [0x029b0000, 0x029b6ff8, 0x029c0000)
  to   space 64K,   0% used [0x029a0000, 0x029a0000, 0x029b0000)
 tenured generation   total 2388K, used 1581K [0x02e00000, 0x03055000, 0x06920000)
   the space 2388K,  66% used [0x02e00000, 0x02f8b580, 0x02f8b600, 0x03055000)
 compacting perm gen  total 12288K, used 5192K [0x06920000, 0x07520000, 0x0a920000)
   the space 12288K,  42% used [0x06920000, 0x06e32008, 0x06e32200, 0x07520000)
No shared spaces configured.

Dynamic libraries:
0x00400000 - 0x0040e000 	y:\disk09\jdk\1.6.0\b43\binaries\win\bin\java.exe
0x7c900000 - 0x7c9b0000 	C:\WINDOWS\system32\ntdll.dll
0x7c800000 - 0x7c8f4000 	C:\WINDOWS\system32\kernel32.dll
0x77dd0000 - 0x77e6b000 	C:\WINDOWS\system32\ADVAPI32.dll
0x77e70000 - 0x77f01000 	C:\WINDOWS\system32\RPCRT4.dll
0x6d090000 - 0x6d0e6000 	y:\disk09\jdk\1.6.0\b43\binaries\win\bin\MSVCR71.dll
0x6d9e0000 - 0x6dbea000 	y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\client\jvm.dll
0x77d40000 - 0x77dd0000 	C:\WINDOWS\system32\USER32.dll
0x77f10000 - 0x77f56000 	C:\WINDOWS\system32\GDI32.dll
0x76b40000 - 0x76b6d000 	C:\WINDOWS\system32\WINMM.dll
0x6d010000 - 0x6d08b000 	y:\disk09\jdk\1.6.0\b43\binaries\win\bin\MSVCP71.dll
0x6d480000 - 0x6d488000 	y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\hpi.dll
0x76bf0000 - 0x76bfb000 	C:\WINDOWS\system32\PSAPI.DLL
0x6d9b0000 - 0x6d9bc000 	y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\verify.dll
0x6d500000 - 0x6d51d000 	y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\java.dll
0x6d9d0000 - 0x6d9df000 	y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\zip.dll
0x6d160000 - 0x6d2e2000 	Y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\awt.dll
0x73000000 - 0x73026000 	C:\WINDOWS\system32\WINSPOOL.DRV
0x77c10000 - 0x77c68000 	C:\WINDOWS\system32\msvcrt.dll
0x76390000 - 0x763ad000 	C:\WINDOWS\system32\IMM32.dll
0x774e0000 - 0x7761d000 	C:\WINDOWS\system32\ole32.dll
0x73760000 - 0x737a9000 	C:\WINDOWS\system32\ddraw.dll
0x73bc0000 - 0x73bc6000 	C:\WINDOWS\system32\DCIMAN32.dll
0x6d430000 - 0x6d47f000 	Y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\fontmanager.dll
0x6d310000 - 0x6d340000 	Y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\cmm.dll
0x6d5c0000 - 0x6d5df000 	Y:\disk09\jdk\1.6.0\b43\binaries\win\jre\bin\jpeg.dll

VM Arguments:
java_command: AnimatedGIFTest
Launcher Type: SUN_STANDARD

Environment Variables:
PROCESSOR_IDENTIFIER=x86 Family 15 Model 2 Stepping 9, GenuineIntel

---------------  S Y S T E M  ---------------

OS: Windows XP Build 2600 Service Pack 2

CPU:total 1 family 15, cmov, cx8, fxsr, mmx, ht

Memory: 4k page, physical 522992k(124092k free), swap 1278288k(859092k free)

vm_info: Java HotSpot(TM) Client VM (1.6.0-ea-b43) for windows-x86, built on Jul 14 2005 01:50:23 by "java_re" with unknown MS VC++:1310

EVALUATION The reason of the problem is that test subsequently reuses same file name to store animated images created with toolkit's getImage(filename). Method getImage() caches images based on their filename using soft hash and there could be of two possible cases: 1. There was no entry in the cache - i.e. this is first run or previous instance was GC-ed. We create new image and everything goes smoothly. 2. There is cached image for the same key (filename). We will create new image decoder but reuse image representation. It might cause us problems - if dimensions are different we get either garbage or crash if buffer was too small. Technically, testcase seems to be perfectly legal. So, we need to resolve it somehow. At the moment i see two possible approaches: - we might be smarter caching images, e.g. use some content digest in addition to filename. This approach is complicated and under some circumstances we still may have similar problems. - we can check for dimensions in the image representation code when we get first portion of image and recreate internal buffered image if dimensions do not match. While image representations were obviously not designed to be reused for other images it seems that later approach is safe enough to resolve this particular problem.

EVALUATION This began crashing in b39. Previous to that release the program doesn't work as it uses the new GIF writer support. The crash appears as a stomp over memory in the Java heap as if some code walked off the end of an array. I added some code to GetPrimitiveArrayCritical to return a copy of the array instead of returning the original array and putback guard regions around the section of memory that was returned. This is a permissible implementation of this function though obivously not as efficient as returning at pointer to the interior of the real array. The code which checks that the guard region asserted in sun.awt.image.ImageRepresentation.setICMpixels so I think the problem is that the code is blindly writing into a Java array without checking that it's properly sized. There's a lot of code which uses GetPrimitiveArrayCritical without checking that the bounds of the code are correct. asserts should be added to check that this code is correct. My guess is that the GIF writer code is producing a GIF that the existing GIF reading code isn't up to handling, resulting in incorrect bounds on the array. I can provide a VM with the JNI debugging support if it's needed. I've attached hs_err_pid2952.log which shows the assertion failure crash in awt.dll. By the way, you can turn the supplied test into an automated test by adding the following code after the call to doTest in the constructor. Thread t = new Thread(new Runnable() { public void run() { while (true) { try { Thread.sleep(2000); } catch (Exception e) { } actionPerformed(null); } } }); t.start(); It's possible actionPerformed should be executed by an invokeLater.

EVALUATION From stack trace it looks like VM issue: =============================================================================== Stack: [0x0f2b0000,0x0f2f0000), sp=0x0f2ef470, free space=253k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [jvm.dll+0x1314c7] V [jvm.dll+0x163e61] J sun.awt.image.ImageRepresentation.setPixels(IIIILjava/awt/image/ColorModel;[B II)V J sun.awt.image.ImageDecoder.setPixels(IIIILjava/awt/image/ColorModel;[BII)I J sun.awt.image.GifImageDecoder.sendPixels(IIII[BLjava/awt/image/ColorModel;)I v ~StubRoutines::call_stub Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) v ~RuntimeStub::monitorexit Runtime1 stub J sun.awt.image.ImageRepresentation.setPixels(IIIILjava/awt/image/ColorModel;[B II)V [error occurred during error reporting, step 130, id 0xe0000000] ================================================================================== The full error log is attached as hs_err_pid3768.log.