Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6604110

DocPrintJob.print is not thread-safe

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • 5.0u21
    • 5.0
    • client-libs
    • 2d
    • x86
    • solaris_2.5.1

      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.

            dmeetry Dmeetry Degrave (Inactive)
            prr Philip Race
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: