[1815585 views]

[]

Odi's astoundingly incomplete notes

New entries | Code

JDK bug in PrintServiceLookup.lookupPrintServices

I have reported the second bug in Sun's JDK-1.5 this year: PrintServiceLookup.lookupPrintServices is not thread-safe on Linux! Most of the time it crashes the VM in an OpenSSL call race and sometimes it just hangs the threads. Workaround: synchronize the call and turn off automatic polling by setting the system property sun.java2d.print.polling=false. Bug report at Sun.

Stack of hanging threads:
Thread 30235: (state = IN_NATIVE)
- sun.print.CUPSPrinter.canConnect(java.lang.String, int) @bci=0 (Interpreted frame)
- sun.print.CUPSPrinter.isCupsRunning() @bci=71, line=352 (Interpreted frame)
- sun.print.UnixPrintServiceLookup.getPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=125, line=351 (Interpreted frame)
- javax.print.PrintServiceLookup.getServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=65, line=359 (Interpreted frame)
- javax.print.PrintServiceLookup.lookupPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=2, line=105 (Interpreted frame)
- Test$Job.run() @bci=42, line=42 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=595 (Interpreted frame)
Thread 30220: (state = IN_NATIVE)
- sun.print.CUPSPrinter.canConnect(java.lang.String, int) @bci=0 (Interpreted frame)
- sun.print.CUPSPrinter.isCupsRunning() @bci=71, line=352 (Interpreted frame)
- sun.print.UnixPrintServiceLookup.getPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=125, line=351 (Interpreted frame)
- javax.print.PrintServiceLookup.getServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=65, line=359 (Interpreted frame)
- javax.print.PrintServiceLookup.lookupPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) @bci=2, line=105 (Interpreted frame)
- Test$Job.run() @bci=42, line=42 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=595 (Interpreted frame)


Stack of crash:
C  [libcrypto.so.4+0x73bda]
C  [libcrypto.so.4+0x73968]  lh_insert+0xc8
C  [libcrypto.so.4+0x760cb]
C  [libcrypto.so.4+0x76753]
C  [libcrypto.so.4+0x766bf]  ERR_load_ERR_strings+0x2f
C  [libcrypto.so.4+0x76795]  ERR_load_strings+0x25
C  [libssl.so.4+0x29fa3]  ERR_load_SSL_strings+0x43
C  [libssl.so.4+0x2124e]  SSL_load_error_strings+0x1e
C  [libcups.so.2+0x5ffe]  httpInitialize+0x5e
C  [libcups.so.2+0x62d8]  httpConnectEncrypt+0x28
C  [libcups.so.2+0x62a8]  httpConnect+0x38
C  [libmawt.so+0x400f]  Java_sun_print_CUPSPrinter_canConnect+0x4f
j  sun.print.CUPSPrinter.canConnect(Ljava/lang/String;I)Z+0
j  sun.print.CUPSPrinter.isCupsRunning()Z+71
j  sun.print.UnixPrintServiceLookup.getPrintServices(Ljavax/print/DocFlavor;Ljavax/print/attribute/AttributeSet;)[Ljavax/print/PrintService;+125
j  javax.print.PrintServiceLookup.getServices(Ljavax/print/DocFlavor;Ljavax/print/attribute/AttributeSet;)Ljava/util/ArrayList;+65
j  javax.print.PrintServiceLookup.lookupPrintServices(Ljavax/print/DocFlavor;Ljavax/print/attribute/AttributeSet;)[Ljavax/print/PrintService;+2
You can easily verify this with the following test case:
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;

/**
 * On JDK-1.5.0_12 on Linux x86 this test case hangs or crashes.
 * 
 * @author Ortwin Glück
 */
public class Test implements Runnable{
    Object latch = new Object();
    
    public static void main(String[] args) {
        Test app = new Test();
        app.run();
    }

    public void run() {
        int THREADS = 200;
        for (int i=0; i<THREADS; i++) {
            Thread t = new Thread(new Job());
            t.setDaemon(false);
            t.start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        
        synchronized (latch) {
            latch.notifyAll();
        }
        
    }
    
    private class Job implements Runnable {

        public void run() {
            synchronized (latch) {
                try {
                    latch.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            PrintService[] services = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, null);
            System.out.println(services.length);
        }
        
    }
}


posted on 2007-08-22 10:55 UTC in Code | 0 comments | permalink