Uploaded image for project: 'PDFBox'
  1. PDFBox
  2. PDFBOX-511

JVM crash in PDColorSpaceInstance.createColor()

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: 0.7.3
    • Fix Version/s: 0.8.0-incubator
    • Component/s: PDModel
    • Labels:
      None
    • Environment:
      Java HotSpot(TM) Client VM (11.3-b02 mixed mode windows-x86), Windows XP Build 2600 Service Pack 3

      Description

      Similar to PDFBOX-488, the JVM (here JDK 1.6 on Windows XP) crashes when PDFBox tries to create a java.awt.Color instance with some specific ICC profile. The root cause of the problem is a low-level bug in the JVM (most likely http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6645513), but it would be really good if PDFBox could work around that issue or at least throw a normal exception in troublesome cases instead of crashing the entire JVM.

      See below for the relevant parts of the crash report.

      #

      1. An unexpected error has been detected by Java Runtime Environment:
        #
      2. EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d17205d, pid=1512, tid=1324
        #
      3. Java VM: Java HotSpot(TM) Client VM (11.3-b02 mixed mode windows-x86)
      4. Problematic frame:
      5. C [cmm.dll+0x205d]
        #
      6. If you would like to submit a bug report, please visit:
      7. http://java.sun.com/webapps/bugreport/crash.jsp
      8. The crash happened outside the Java Virtual Machine in native code.
      9. See problematic frame for where to report the bug.
        #

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

      Current thread (0x492f6800): JavaThread "pool-3-thread-11" [_thread_in_native,
      id=1324, stack(0x4aa40000,0x4aa90000)]

      siginfo: ExceptionCode=0xc0000005, writing address 0x00000008

      Registers:
      EAX=0x001cc20b, EBX=0x4aa8eda0, ECX=0x00000000, EDX=0x6d19c88c
      ESP=0x4aa8ed34, EBP=0x4aa8edc0, ESI=0x4aa8ed6c, EDI=0x00000003
      EIP=0x6d17205d, EFLAGS=0x00010246

      Top of Stack: (sp=0x4aa8ed34)
      0x4aa8ed34: 00000008 000000ff 4aa8ee34 73a6ef68
      0x4aa8ed44: 790739f0 5577e7e0 00000000 00000000
      0x4aa8ed54: 00000000 00000000 00000000 7dff9f58
      0x4aa8ed64: 5d29bb60 7e87fca0 00000000 00000000
      0x4aa8ed74: 00000000 00000000 00000000 565bff20
      0x4aa8ed84: 618b6ca0 618b6d50 581b1ed8 00000000
      0x4aa8ed94: 00000000 00000000 00000000 00000003
      0x4aa8eda4: 6d173f79 00000000 3ff00000 0000000f

      Instructions: (pc=0x6d17205d)
      0x6d17204d: 83 c4 14 89 06 e8 e8 34 02 00 83 7d 1c 00 8b 0e
      0x6d17205d: 89 41 08 74 0e 8b 45 f8 8b 34 30 85 f6 74 04 8b

      Stack: [0x4aa40000,0x4aa90000], sp=0x4aa8ed34, free space=315k
      Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
      C [cmm.dll+0x205d]
      C [cmm.dll+0x40f1]
      C [cmm.dll+0x435e]
      C [cmm.dll+0x1ff75]
      C [cmm.dll+0x20413]

      Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
      J sun.awt.color.CMM.cmmCombineTransforms([Lsun/awt/color/ICC_Transform;Lsun/awt/color/ICC_Transform;)I
      J java.awt.color.ICC_ColorSpace.toRGB([F)[F
      J java.awt.Color.<init>(Ljava/awt/color/ColorSpace;[FF)V
      J org.apache.pdfbox.pdmodel.graphics.color.PDColorSpaceInstance.createColor()Ljava/awt/Color;
      J org.apache.pdfbox.pdfviewer.PageDrawer.fillPath(I)V
      J org.apache.pdfbox.util.operator.pagedrawer.FillNonZeroRule.process(Lorg/apache/pdfbox/util/PDFOperator;Ljava/util/List;)V
      J org.apache.pdfbox.util.PDFStreamEngine.processOperator(Lorg/apache/pdfbox/util/PDFOperator;Ljava/util/List;)V
      J org.apache.pdfbox.util.PDFStreamEngine.processSubStream(Lorg/apache/pdfbox/pdmodel/PDPage;Lorg/apache/pdfbox/pdmodel/PDResources;Lorg/apache/pdfbox/cos/COSStream;)V
      j org.apache.pdfbox.util.operator.pagedrawer.Invoke.process(Lorg/apache/pdfbox/util/PDFOperator;Ljava/util/List;)V+419
      J org.apache.pdfbox.util.PDFStreamEngine.processOperator(Lorg/apache/pdfbox/util/PDFOperator;Ljava/util/List;)V
      J org.apache.pdfbox.util.PDFStreamEngine.processSubStream(Lorg/apache/pdfbox/pdmodel/PDPage;Lorg/apache/pdfbox/pdmodel/PDResources;Lorg/apache/pdfbox/cos/COSStream;)V
      j org.apache.pdfbox.util.PDFStreamEngine.processStream(Lorg/apache/pdfbox/pdmodel/PDPage;Lorg/apache/pdfbox/pdmodel/PDResources;Lorg/apache/pdfbox/cos/COSStream;)V+39
      j org.apache.pdfbox.pdfviewer.PageDrawer.drawPage(Ljava/awt/Graphics;Lorg/apache/pdfbox/pdmodel/PDPage;Ljava/awt/Dimension;)V+57
      j org.apache.pdfbox.pdmodel.PDPage.convertToImage()Ljava/awt/image/BufferedImage;+107

      1. PDFBOX-511.patch
        4 kB
        Jukka Zitting
      2. PDFBOX-511.patch
        2 kB
        Jukka Zitting

        Activity

        Hide
        jukkaz Jukka Zitting added a comment -

        JVM issues like http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6295525 suggest that this problem doesn't affect just some specific ICC profiles, but may be related to the interaction between the garbage collector and generic ICC data structures. I have reports of this from both Sun Java 5 and 6, so I can only assume that this crash can randomly occur with any ICC profiles on any currently supported Sun Java version.

        As a first workaround I attached a patch that throws an exception from PDColorSpaceInstance.createColor() whenever an ICC color profile is used. Note that this change breaks any uses of the PageDrawer with PDFs that use ICC color profiles!

        The safety measure can be disabled by explicitly setting the "org.apache.pdfbox.ICC_safety_override" system property to "true". It would also be possible (though IMHO unsafe) to reverse the override mechanism to keep the current behaviour as the default and to avoid ICC profiles only when explicitly asked. We could also selectively enable ICC processing for non-Sun class libraries.

        Show
        jukkaz Jukka Zitting added a comment - JVM issues like http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6295525 suggest that this problem doesn't affect just some specific ICC profiles, but may be related to the interaction between the garbage collector and generic ICC data structures. I have reports of this from both Sun Java 5 and 6, so I can only assume that this crash can randomly occur with any ICC profiles on any currently supported Sun Java version. As a first workaround I attached a patch that throws an exception from PDColorSpaceInstance.createColor() whenever an ICC color profile is used. Note that this change breaks any uses of the PageDrawer with PDFs that use ICC color profiles! The safety measure can be disabled by explicitly setting the "org.apache.pdfbox.ICC_safety_override" system property to "true". It would also be possible (though IMHO unsafe) to reverse the override mechanism to keep the current behaviour as the default and to avoid ICC profiles only when explicitly asked. We could also selectively enable ICC processing for non-Sun class libraries.
        Hide
        jukkaz Jukka Zitting added a comment -

        It looks like the above proposal would affect too many PDF documents, so I changed my mind and instead changed the patch to require action to enable this workaround. In the attached new version I also simply replace any ICC colors with a specified override color instead of throwing an IOException in such cases. This way the output from PageDrawer should still be usable if not entirely correct when the workaround has been enabled.

        To enable the workaround, either specify the following system property

        -Dorg.apache.pdfbox.ICC_override_color=0

        or call the new static method

        PDColorSpaceInstance.setIccOverrideColor(Color.BLACK)

        You can use any color you want as the override. The system property is an integer color code, see java.awt.Color for details.

        Show
        jukkaz Jukka Zitting added a comment - It looks like the above proposal would affect too many PDF documents, so I changed my mind and instead changed the patch to require action to enable this workaround. In the attached new version I also simply replace any ICC colors with a specified override color instead of throwing an IOException in such cases. This way the output from PageDrawer should still be usable if not entirely correct when the workaround has been enabled. To enable the workaround, either specify the following system property -Dorg.apache.pdfbox.ICC_override_color=0 or call the new static method PDColorSpaceInstance.setIccOverrideColor(Color.BLACK) You can use any color you want as the override. The system property is an integer color code, see java.awt.Color for details.
        Hide
        jukkaz Jukka Zitting added a comment -

        I committed the patch in revision 814536.

        While reviewing the code I found out that new java.awt.Color instances are getting created whenever a new drawing operation is performed. With some refactoring it should be possible to reduce the number of new Color instances to only the number times the color actually changes due to SetStroking- or SetNonStrokingColor operations. Since the above-mentioned JVM crash is non-deterministic and especially since it seems to be related to garbage-collection, reducing the number of createColor() calls and short-lived color space instances should notably reduce the likelihood of these crashes.

        Show
        jukkaz Jukka Zitting added a comment - I committed the patch in revision 814536. While reviewing the code I found out that new java.awt.Color instances are getting created whenever a new drawing operation is performed. With some refactoring it should be possible to reduce the number of new Color instances to only the number times the color actually changes due to SetStroking- or SetNonStrokingColor operations. Since the above-mentioned JVM crash is non-deterministic and especially since it seems to be related to garbage-collection, reducing the number of createColor() calls and short-lived color space instances should notably reduce the likelihood of these crashes.
        Hide
        jukkaz Jukka Zitting added a comment -

        I refactored the code to only create new Java AWT Color and ColorSpace instances when actually needed. In a test document I have this reduced the number of Color and ColorSpace instances from 5000+ to 1007 and 21 respectively. This means 80% fewer createColor() calls and >99% fewer ICC_ColorSpace instances, which dramatically reduces the likelihood of the crash.

        Together with the optional override mechanism I implemented earlier this is about as much as we can do in PDFBox, so I'm resolving this issue as Fixed.

        Show
        jukkaz Jukka Zitting added a comment - I refactored the code to only create new Java AWT Color and ColorSpace instances when actually needed. In a test document I have this reduced the number of Color and ColorSpace instances from 5000+ to 1007 and 21 respectively. This means 80% fewer createColor() calls and >99% fewer ICC_ColorSpace instances, which dramatically reduces the likelihood of the crash. Together with the optional override mechanism I implemented earlier this is about as much as we can do in PDFBox, so I'm resolving this issue as Fixed.

          People

          • Assignee:
            jukkaz Jukka Zitting
            Reporter:
            jukkaz Jukka Zitting
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development