JDK-4896773 : Rendering CubicCurve2D with NaN as control points causes crash in ductus code
  • Type: Bug
  • Status: Resolved
  • Resolution: Fixed
  • Component: client-libs
  • Sub-Component: 2d
  • Priority: P3
  • Affected Version: 1.4.2,5.0,6
  • OS: solaris_8,solaris_9,windows_xp
  • CPU: x86,sparc
  • Submit Date: 2003-07-25
  • Updated Date: 2005-05-31
  • Resolved Date: 2005-05-31
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 Availabitlity Release.

To download the current JDK release, click here.
Other JDK 6
1.4.2_09Resolved 6 betaResolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
If some race condition causes the graphical view to try and paint when
the data hasn't been filled in yet, JVM hangs or crashes.  It seems which one it does depends on the AffineTransform being used at the time.  A transform of
[-1,-1] results in a crash; [1,1], a hang.

The program below (CrashVM2.java) takes an argument of either "-crash" or "-hang":


*****

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.RenderingHints;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class CrashVM2 extends JPanel {

    CubicCurve2D.Double s1 = null;
    static boolean crash = false;

    public static void main(String[] args) {
        if (args.length != 1) {
            usage();
        }
        if (args[0].equals("-crash")) {
            crash = true;
        } else if (args[0].equals("-hang")) {
            crash = false;
        } else {
            usage();
        }
        JFrame f = new JFrame();
        f.getContentPane().add(new CrashVM2());
        f.setSize(640, 480);
        f.setVisible(true);
    }

    public static void usage() {
        System.out.println("Usage: CrashVM2 [-crash | -hang ]");
        System.exit(1);
    }
    
    
    public CrashVM2() {
        s1 =  new CubicCurve2D.Double();
        s1.setCurve(1.0, 1.0,
                   Double.NaN, Double.NaN,
                   Double.NaN, Double.NaN,
                   0.0, 0.0);
    }
    
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                             RenderingHints.VALUE_ANTIALIAS_ON);
        System.out.println("About to draw...");
        AffineTransform oldTransform = g2.getTransform();
        AffineTransform downRight = (AffineTransform) oldTransform.clone();
        AffineTransform upLeft = (AffineTransform) oldTransform.clone();
        downRight.translate(1.0,1.0);
        upLeft.translate(-1.0,-1.0);
        g2.setTransform(crash ? upLeft : downRight);
        g2.draw(s1);
        g2.setTransform(oldTransform);
        System.out.println("Done --> " + new Date().toString());
    }

}

****************



Comments
WORK AROUND The workaround for this is : Don't use AntiAliasing: Comment out the line 50 // g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 51 // RenderingHints.VALUE_ANTIALIAS_ON);
2004-08-21

EVALUATION Application creates a CubicCurve with NaNs as control points: s1 = new CubicCurve2D.Double(); s1.setCurve(1.0, 1.0, Double.NaN, Double.NaN, Double.NaN, Double.NaN, 0.0, 0.0); So we're crashing in ductus renderer running out of stack: t@17 (l@18) signal SEGV (access to address exceeded protections) in processToRunsArc3 at line 729 in file "dcPathFiller.c" 729 if (x0 < x1) { arclox = x0; archix = x1; } dbx: read of 32 bytes at address f1d07f78 failed -- Error 0 (dbx 5) w current thread: t@17 =>[1] processToRunsArc3(env = (nil), p = (nil), x0 = 0.01564897, y0 = 0.03124998, x1 = NaN, y1 = NaN, x2 = NaN, y2 = NaN, x3 = NaN, y3 = NaN), line 729 in "dcPathFiller.c" [2] processToRunsArc3(env = 0x87638, p = 0x16261c, x0 = 0.01564897, y0 = 0.03124998, x1 = NaN, y1 = NaN, x2 = NaN, y2 = NaN, x3 = NaN, y3 = NaN), line 814 in "dcPathFiller.c" [3] processToRunsArc3(env = 0x87638, p = 0x16261c, x0 = 0.01564897, y0 = 0.03124998, x1 = NaN, y1 = NaN, x2 = NaN, y2 = NaN, x3 = NaN, y3 = NaN), line 814 in "dcPathFiller.c" Note that we do not crash on windows because for some reason instead of RunsBuilder_appendCubic (dcPathFiller) on solaris, which calls processToRunsArc3, we call RunsBuilder_appendLine. I'm reassigning the bug to the engineer working on boundary conditions in Ductus renderer. I don't believe this is a high priority bug: the app supplies unreasonable input. While we definitely shouldn't crash, the workaround for the customer is simple: chose some reasonable default values instead of NaNs. ###@###.### 2003-08-21 Fixed at java level by validating path segments and skiping ones with invalid control points ###@###.### 2005-04-27 17:29:15 GMT
2003-08-21