JDK-6604110 : DocPrintJob.print is not thread-safe
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_2.5.1
  • CPU: x86
  • Submitted: 2007-09-13
  • Updated: 2011-02-16
  • Resolved: 2009-07-21
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.
Other
5.0u21Resolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_12-b04)
Java HotSpot(TM) Server VM (build 1.5.0_12-b04, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux sg1315z 2.4.21-37.ELsmp #1 SMP Wed Sep 7 13:28:55 EDT 2005 i686 i686 i386 GNU/Linux

EXTRA RELEVANT SYSTEM CONFIGURATION :
118 CUPS printers on Windows lp queues.

A DESCRIPTION OF THE PROBLEM :
VM crashes if documents are printed concurrently to different printers.
It seems that OpenSSL is called concurrently which leads to memory corruption.
I have not checked if it still happens with 1.6, but this is a severe defect in 1.5 that should be fixed.

This report is related to the one filed earlier with the internal review ID 1040104.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Define two CUPS printers. Preferrably over Windows lp queues.
2. Obtain a PDF file that you can print.
3. Print the file from multiple threads concurrently to the two printers.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Documents are printed.
ACTUAL -
VM crashes after some time.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  SIGSEGV (0xb) at pc=0xb7507cee, pid=19281, tid=1816099760
#
# Java VM: Java HotSpot(TM) Server VM (1.5.0_12-b04 mixed mode)
# Problematic frame:
# C  [libc.so.6+0x71cee]
#

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

Current thread (0x081148a8):  JavaThread "Thread-10" [_thread_in_native, id=19879]

siginfo:si_signo=11, si_errno=0, si_code=1, si_addr=0x00000009

Registers:
EAX=0x0000001b, EBX=0xb75cbcd8, ECX=0x00000048, EDX=0xb75cc5cc
ESP=0x6c3f6f74, EBP=0x6c3f6fa8, ESI=0x00000001, EDI=0x00000001
EIP=0xb7507cee, CR2=0x00000009, EFLAGS=0x00010202

  Top of Stack: (sp=0x6c3f6f74)
0x6c3f6f74:   6c3f701c 081961ac 081927f8 08093ec0
0x6c3f6f84:   6c3f6fa4 6ce87662 00000001 6cee273c
0x6c3f6f94:   00000018 b75cc5c0 b75cbcd8 b75cc5c0
0x6c3f6fa4:   00000001 6c3f6fc4 b75070fd b75cc5c0
0x6c3f6fb4:   00000010 6cefcbf8 00000002 00000010
0x6c3f6fc4:   6c3f6fd4 6ce3a500 00000010 6cefcbf8
0x6c3f6fd4:   6c3f7004 6ce3ab5c 00000010 6cee244b
0x6c3f6fe4:   000000ba 6ce3ae2d 6d8d4680 00000000

Instructions: (pc=0xb7507cee)
0xb7507cde:   75 ec d1 ee 01 f2 8b 72 10 85 f6 89 75 e4 74 0d
0xb7507cee:   8b 7e 08 89 f0 89 7a 10 83 c0 08 eb b6 81 7d ec

Stack: [0x6c377000,0x6c3f8000),  sp=0x6c3f6f74,  free space=511k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libc.so.6+0x71cee]
C  [libc.so.6+0x710fd]  malloc+0x8d
C  [libcrypto.so.4+0x2b500]
C  [libcrypto.so.4+0x2bb5c]  CRYPTO_malloc+0x4c
C  [libcrypto.so.4+0x7883e]  OBJ_NAME_add+0x5e
C  [libcrypto.so.4+0x7d2ee]  EVP_add_cipher+0x6e
C  [libssl.so.4+0x29283]  SSL_library_init+0x33
C  [libcups.so.2+0x6003]  httpInitialize+0x63
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.UnixPrintJob.print(Ljavax/print/Doc;Ljavax/print/attribute/PrintRequestAttributeSet;)V+186
j  Test$Job.run()V+171
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub
V  [libjvm.so+0x267d7c]
V  [libjvm.so+0x437618]
V  [libjvm.so+0x2675d5]
V  [libjvm.so+0x26766e]
V  [libjvm.so+0x2df635]
V  [libjvm.so+0x4d7d13]
V  [libjvm.so+0x438228]
C  [libpthread.so.0+0x4dd8]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  sun.print.CUPSPrinter.canConnect(Ljava/lang/String;I)Z+0
j  sun.print.CUPSPrinter.isCupsRunning()Z+71
j  sun.print.UnixPrintJob.print(Ljavax/print/Doc;Ljavax/print/attribute/PrintRequestAttributeSet;)V+186
j  Test$Job.run()V+171
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub

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

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

OS:Red Hat Enterprise Linux AS release 3 (Taroon Update 6)

uname:Linux 2.4.21-37.ELsmp #1 SMP Wed Sep 7 13:28:55 EDT 2005 i686
libc:glibc 2.3.2 NPTL 0.60
rlimit: STACK 10240k, CORE 0k, NPROC 7168, NOFILE 8192, AS infinity
load average:0.06 0.04 0.01

CPU:total 4 (cores per cpu 1, threads per core 2) family 15 model 2 stepping 5, cmov, cx8, fxsr, mmx, sse, sse2, ht

Memory: 4k page, physical 4101336k(27296k free), swap 249k(229k free)

vm_info: Java HotSpot(TM) Server VM (1.5.0_12-b04) for linux-x86, built on May  2 2007 02:13:16 by java_re with gcc 3.2.1-7a (J2SE release)



REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicInteger;

import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;

/**
 * Crashes on Linux when printing a PDF to two different printers.
 *
 * @author Ortwin Gl��ck
 */
public class Test implements Runnable{
    private static AtomicInteger select = new AtomicInteger();
    private PrintService service1, service2;
    private Object latch = new Object();
    private String file;
    
    public static void main(String[] args) {
        if (args.length != 3) {
            System.out.println("Syntax: Test printer printer file");
            return;
        }
        Test app = new Test(args[0], args[1], args[2]);
        app.run();
    }
    
    public Test(String printer1, String printer2, String file) {
        PrintService[] services = PrintServiceLookup.lookupPrintServices(DocFlavor.INPUT_STREAM.AUTOSENSE, null);
        for (PrintService ps : services) {
            if (printer1.equals(ps.getName())) {
                service1 = ps;
            }
            if (printer2.equals(ps.getName())) {
                service2 = ps;
            }
        }
        if (service1 == null)
            throw new IllegalArgumentException("Unknown printer "+ printer1);
        if (service2 == null)
            throw new IllegalArgumentException("Unknown printer "+ printer2);
        File f = new File(file);
        if (!f.exists())
            throw new IllegalArgumentException("File not found: "+ f.getAbsolutePath());
        if (!f.isFile())
            throw new IllegalArgumentException("Not a file: "+ f.getAbsolutePath());
        this.file = file;
    }

    public void run() {
        int THREADS = 20;
        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();
                }
            }
            InputStream stream;
            try {
                stream = new FileInputStream(file);
            } catch(FileNotFoundException e) {
                // does not happen
                throw new RuntimeException(e.getMessage(), e);
            }
            
            DocPrintJob dpj;
            if (select.getAndIncrement() % 2 == 0) {
                dpj = service1.createPrintJob();
            } else {
                dpj = service2.createPrintJob();
            }
            DocAttributeSet docaset = new HashDocAttributeSet();
            docaset.add(MediaSizeName.ISO_A4);
            SimpleDoc simpleDoc = new SimpleDoc(stream, DocFlavor.INPUT_STREAM.AUTOSENSE, docaset);
            PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
            aset.add(MediaSizeName.ISO_A4);
            try {
                //synchronized (Test.this) {
                    dpj.print(simpleDoc, aset);
                //}
            } catch(Exception e) {
                System.err.print(e.getMessage());
            }
        }
        
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Synchronize all calls to the printing API with a global lock.