United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4896773 : Rendering CubicCurve2D with NaN as control points causes crash in ductus code

Details
Type:
Bug
Submit Date:
2003-07-25
Status:
Resolved
Updated Date:
2005-05-31
Project Name:
JDK
Resolved Date:
2005-05-31
Component:
client-libs
OS:
solaris_9,solaris_8,windows_xp
Sub-Component:
2d
CPU:
x86,sparc
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.2,5.0,6
Fixed Versions:

Related Reports
Backport:
Backport:
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

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



Hardware and Software, Engineered to Work Together