JDK-6358747 : PrinterJob.printDialog() crashes JVM when called from subthread
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 5.0,5.0u2,5.0u10,5.0u11
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp,windows_vista
  • CPU: other,x86
  • Submitted: 2005-12-03
  • Updated: 2014-02-27
  • Resolved: 2007-06-27
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 JDK 6 JDK 7
5.0u11 b02Fixed 6u2Fixed 7Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode, sharing)

FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]

EXTRA RELEVANT SYSTEM CONFIGURATION :
Appears to be printer independent.

A DESCRIPTION OF THE PROBLEM :
calling PrinterJob.printDialog() from a subthread crashes the JVM. This looks like a timing-related issue, since it crashes the JVM only in abut 50% of the cases.

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Yes

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Did not try

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the program below, not with debugger (this reduces the chance of a crash). Click OK on the page setup dialog. After that the program crashes the JVM in most caes 8 out of 10.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected is that after the step above a print dialog appears, but instead the JVM crashes.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
================ Error test on console: ======================
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x755c4f0d, pid=4984, tid=4060
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_02-b09 mixed mode, sharing)
# Problematic frame:
# C  [msctfime.ime+0x4f0d]
#
# An error report file with more information is saved as hs_err_pid4984.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

[error occurred during error reporting, step 270, id 0xc0000005]

============= contents of sump file: ==================
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x755c4f0d, pid=4984, tid=4060
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_02-b09 mixed mode, sharing)
# Problematic frame:
# C  [msctfime.ime+0x4f0d]
#

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

Current thread (0x00840e80):  JavaThread "AWT-Windows" daemon [_thread_in_native, id=4060]

siginfo: ExceptionCode=0xc0000005, reading address 0x006e0069

Registers:
EAX=0x006e0069, EBX=0x00000000, ECX=0x0319e738, EDX=0x00080608
ESP=0x0319e718, EBP=0x0319e71c, ESI=0x0319e738, EDI=0x000911e8
EIP=0x755c4f0d, EFLAGS=0x00010206

  Top of Stack: (sp=0x0319e718)
0x0319e718:   0319e738 0319e72c 755c5179 006e0069
0x0319e728:   80004005 0319e740 755c552b 006e0069
0x0319e738:   755c1454 006e0069 0319e784 755c567c
0x0319e748:   0319e77c 0319e76c 000911e8 000b0a40
0x0319e758:   755c1444 000c2f50 03b70bab 00000000
0x0319e768:   00000000 755c1520 000ce078 00a20024
0x0319e778:   00000000 755c62bf 000b0a40 0319e7d4
0x0319e788:   755c62ce 000c7c70 00000000 00010c8b

Instructions: (pc=0x755c4f0d)
0x755c4efd:   85 c0 56 8b f1 89 46 04 c7 06 54 14 5c 75 74 06
0x755c4f0d:   8b 08 50 ff 51 04 8b c6 5e 5d c2 04 00 cc cc cc


Stack: [0x03160000,0x031a0000),  sp=0x0319e718,  free space=249k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [msctfime.ime+0x4f0d]
C  [msctfime.ime+0x5179]
C  [msctfime.ime+0x552b]
C  [msctfime.ime+0x567c]
C  [msctfime.ime+0x62ce]
C  [msctfime.ime+0x6f7a]
C  [msctfime.ime+0x196e0]
C  [IMM32.DLL+0x2ae3]
C  [USER32.dll+0x5b4ae]
C  [USER32.dll+0x5b991]
C  [USER32.dll+0x5c46b]
C  [USER32.dll+0x5c519]
C  [USER32.dll+0x8709]
C  [USER32.dll+0x87eb]
C  [USER32.dll+0xb368]
C  [USER32.dll+0xb3b4]
C  [ntdll.dll+0xeae3]
C  [COMDLG32.DLL+0x230be]
C  [USER32.dll+0x8709]
C  [USER32.dll+0x151cd]
C  [USER32.dll+0x14af2]
C  [USER32.dll+0x14d1c]
C  [USER32.dll+0x8709]
C  [USER32.dll+0x87eb]
C  [USER32.dll+0xb743]
C  [USER32.dll+0x158ef]
C  [USER32.dll+0x16877]
C  [USER32.dll+0x168cc]
C  [COMDLG32.DLL+0x2332a]
C  [COMDLG32.DLL+0x238d7]
C  [COMDLG32.DLL+0x2479f]
C  [awt.dll+0xd9d7e]
C  [USER32.dll+0x8709]
C  [USER32.dll+0x87eb]
C  [USER32.dll+0xb368]
C  [USER32.dll+0xb3b4]
C  [ntdll.dll+0xeae3]
C  [USER32.dll+0x93df]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  sun.awt.windows.WToolkit.eventLoop()V+0
j  sun.awt.windows.WToolkit.run()V+69
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub

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

Java Threads: ( => current thread )
  0x00846390 JavaThread "Thread-3" [_thread_in_native, id=5196]
  0x00845b10 JavaThread "DestroyJavaVM" [_thread_blocked, id=5180]
  0x00842130 JavaThread "AWT-EventQueue-0" [_thread_in_native, id=5176]
=>0x00840e80 JavaThread "AWT-Windows" daemon [_thread_in_native, id=4060]
  0x0083f4a0 JavaThread "AWT-Shutdown" [_thread_blocked, id=4124]
  0x0083ae80 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=5920]
  0x008319e0 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=5036]
  0x00830e70 JavaThread "CompilerThread0" daemon [_thread_blocked, id=3116]
  0x0082fc40 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=3344]
  0x0082ed40 JavaThread "Finalizer" daemon [_thread_blocked, id=5028]
  0x0082dad0 JavaThread "Reference Handler" daemon [_thread_blocked, id=4804]

Other Threads:
  0x0082cd20 VMThread [id=4960]
  0x00834d90 WatcherThread [id=5040]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap
 def new generation   total 576K, used 501K [0x22cd0000, 0x22d70000, 0x231b0000)
  eden space 512K,  85% used [0x22cd0000, 0x22d3d670, 0x22d50000)
  from space 64K, 100% used [0x22d60000, 0x22d70000, 0x22d70000)
  to   space 64K,   0% used [0x22d50000, 0x22d50000, 0x22d60000)
 tenured generation   total 1408K, used 182K [0x231b0000, 0x23310000, 0x26cd0000)
   the space 1408K,  12% used [0x231b0000, 0x231ddbf0, 0x231ddc00, 0x23310000)
 compacting perm gen  total 8192K, used 359K [0x26cd0000, 0x274d0000, 0x2acd0000)
   the space 8192K,   4% used [0x26cd0000, 0x26d29c20, 0x26d29e00, 0x274d0000)
    ro space 8192K,  62% used [0x2acd0000, 0x2b1d8018, 0x2b1d8200, 0x2b4d0000)
    rw space 12288K,  46% used [0x2b4d0000, 0x2ba5c620, 0x2ba5c800, 0x2c0d0000)

Dynamic libraries:
0x00400000 - 0x0040c000 	C:\Program Files\Java\jre1.5.0_02\bin\javaw.exe
0x7c900000 - 0x7c9b0000 	C:\WINDOWS\system32\ntdll.dll
0x7c800000 - 0x7c8f4000 	C:\WINDOWS\system32\kernel32.dll
0x77dd0000 - 0x77e6b000 	C:\WINDOWS\system32\ADVAPI32.dll
0x77e70000 - 0x77f01000 	C:\WINDOWS\system32\RPCRT4.dll
0x77d40000 - 0x77dd0000 	C:\WINDOWS\system32\USER32.dll
0x77f10000 - 0x77f56000 	C:\WINDOWS\system32\GDI32.dll
0x77c10000 - 0x77c68000 	C:\WINDOWS\system32\MSVCRT.dll
0x76390000 - 0x763ad000 	C:\WINDOWS\system32\IMM32.DLL
0x629c0000 - 0x629c9000 	C:\WINDOWS\system32\LPK.DLL
0x74d90000 - 0x74dfb000 	C:\WINDOWS\system32\USP10.dll
0x67900000 - 0x6793a000 	C:\Program Files\Norman\Nvc\BIN\Niphk.dll
0x77120000 - 0x771ac000 	C:\WINDOWS\system32\OLEAUT32.dll
0x774e0000 - 0x7761d000 	C:\WINDOWS\system32\ole32.dll
0x6d640000 - 0x6d7c5000 	C:\Program Files\Java\jre1.5.0_02\bin\client\jvm.dll
0x76b40000 - 0x76b6d000 	C:\WINDOWS\system32\WINMM.dll
0x6d280000 - 0x6d288000 	C:\Program Files\Java\jre1.5.0_02\bin\hpi.dll
0x76bf0000 - 0x76bfb000 	C:\WINDOWS\system32\PSAPI.DLL
0x6d610000 - 0x6d61c000 	C:\Program Files\Java\jre1.5.0_02\bin\verify.dll
0x6d300000 - 0x6d31d000 	C:\Program Files\Java\jre1.5.0_02\bin\java.dll
0x6d630000 - 0x6d63f000 	C:\Program Files\Java\jre1.5.0_02\bin\zip.dll
0x6d000000 - 0x6d166000 	C:\Program Files\Java\jre1.5.0_02\bin\awt.dll
0x73000000 - 0x73026000 	C:\WINDOWS\system32\WINSPOOL.DRV
0x5ad70000 - 0x5ada8000 	C:\WINDOWS\system32\uxtheme.dll
0x73760000 - 0x737a9000 	C:\WINDOWS\system32\ddraw.dll
0x73bc0000 - 0x73bc6000 	C:\WINDOWS\system32\DCIMAN32.dll
0x73940000 - 0x73a10000 	C:\WINDOWS\system32\D3DIM700.DLL
0x6d240000 - 0x6d27d000 	C:\Program Files\Java\jre1.5.0_02\bin\fontmanager.dll
0x74720000 - 0x7476b000 	C:\WINDOWS\system32\MSCTF.dll
0x755c0000 - 0x755ee000 	C:\WINDOWS\system32\msctfime.ime
0x77fe0000 - 0x77ff1000 	C:\WINDOWS\system32\Secur32.dll
0x76fd0000 - 0x7704f000 	C:\WINDOWS\system32\CLBCATQ.DLL
0x77050000 - 0x77115000 	C:\WINDOWS\system32\COMRes.dll
0x77c00000 - 0x77c08000 	C:\WINDOWS\system32\VERSION.dll
0x605d0000 - 0x605d9000 	C:\WINDOWS\system32\mslbui.dll
0x7c9c0000 - 0x7d1d4000 	C:\WINDOWS\system32\shell32.dll
0x77f60000 - 0x77fd6000 	C:\WINDOWS\system32\SHLWAPI.dll
0x773d0000 - 0x774d2000 	C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll
0x5d090000 - 0x5d127000 	C:\WINDOWS\system32\comctl32.dll
0x763b0000 - 0x763f9000 	C:\WINDOWS\system32\COMDLG32.DLL
0x60600000 - 0x60644000 	C:\WINDOWS\System32\spool\DRIVERS\W32X86\3\hpzntp04.dll
0x10000000 - 0x1001e000 	C:\WINDOWS\System32\spool\DRIVERS\W32X86\3\hpz2ku04.dll

VM Arguments:
jvm_args: -enableassertions -Xbootclasspath:C:\Program Files\Java\jre1.5.0_02\lib\rt.jar;C:\Program Files\Java\jre1.5.0_02\lib\jsse.jar;C:\Program Files\Java\jre1.5.0_02\lib\jce.jar;C:\Program Files\Java\jre1.5.0_02\lib\charsets.jar;C:\Program Files\Java\jre1.5.0_02\lib\ext\dnsns.jar;C:\Program Files\Java\jre1.5.0_02\lib\ext\localedata.jar;C:\Program Files\Java\jre1.5.0_02\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jre1.5.0_02\lib\ext\sunpkcs11.jar
java_command: nl.timeware.bizsim.bizedit.BizEditApp

Environment Variables:
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Common Files\Adaptec Shared\System
USERNAME=paul
OS=Windows_NT
PROCESSOR_IDENTIFIER=x86 Family 6 Model 8 Stepping 3, GenuineIntel


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

OS: Windows XP Build 2600 Service Pack 2

CPU:total 1 family 6, cmov, cx8, fxsr, mmx, sse

Memory: 4k page, physical 523496k(31028k free), swap 1540588k(196788k free)

vm_info: Java HotSpot(TM) Client VM (1.5.0_02-b09) for windows-x86, built on Mar  4 2005 01:53:53 by "java_re" with MS VC++ 6.0



REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
package nl.timeware.bizsim.bizedit;
import java.awt.Graphics;
import java.awt.print.*;
import javax.swing.*;
import javax.swing.SwingUtilities;

public class CrashJVM
{ static public void main(String[] args)
  {  new AFrame().setVisible(true);
  }
  private static class AFrame extends JFrame
  {  public AFrame()
     {  final APanel aPanel = new APanel();
        SwingUtilities.invokeLater(new Runnable()
             {   public void run()
                 { aPanel.startPrint();
                 }
             });
     }
  }
  private static class APanel extends JPanel
  {  private APrintable report;
     public APanel()
     {   report = new APrintable();
     }
     public Book getBook(PageFormat format)
     {  return report.getBook(format);
     }
     public void startPrint()
     {  PrinterJob job = PrinterJob.getPrinterJob();
        Paper a4Paper = new Paper();
        a4Paper.setSize(595, 840);
        a4Paper.setImageableArea(40, 40, 515, 760);
        PageFormat pageFormat = job.defaultPage();
        pageFormat.setOrientation(PageFormat.PORTRAIT);
        pageFormat.setPaper(a4Paper);
        pageFormat = job.pageDialog(pageFormat);
        job.setPageable(getBook(pageFormat));
        job.printDialog(); // <-- crashes the JVM
     }
     private class APrintable extends JPanel implements Printable
     {  public Book getBook(PageFormat format)
        {  return new PrintBook(format);
        }
        public int print(Graphics g, PageFormat format, int page)
        {  return PAGE_EXISTS;
        }
        private class PrintBook extends Book
        {  public PrintBook(PageFormat format)
           { append(APrintable.this, format, 1);
           }
        }
     }
  }
}


---------- END SOURCE ----------
Submitter provided the following two updates 

I tested this this today with 1.5.0_06. It still results in the same JVM 
crash.
I tested it with several types of printers:
- local printer HP d135, driver version 1.0 (USB),
- network printer, HP 4550, driver version 2.0.5
- fax, HP d135, driver version 1.0 (USB),
- PDF driver, Jaws PdfCreator 3.0
They all result in the same crash. So, I really don't believe it's a 
printer driver issue.
I tried it on several computers, but got the error only on the following 
computer:
- A Dell OptiPlex GX200, the CPU is an Processor Pentium III, Family 6 
Model 8 Stepping 3 GenuineIntel ~662 Mhz.
- I was using Windows XP home (version 2002, SP-2, build 2600, with all 
updates installed).

------------------------------------

Just tried with mustang dated Dec 1. Got same crash.
No crash on:
- DELL Inspiron 5160, Pentium 4, 2.80 GHz
- DELL Inspiron 1150, Intel Celeron, 2.40 GHz
- DELL Dimension 4600, Pentium 4, 2.40 GHz
- DELL Dimension 200, Intel Celeron, 1.10 Ghz
All with Windows XP home (version 2002, SP-2, build 2600, with all 
updates installed).

Maybe more interesting: I just found that it only crashes if I run the 
program under
my Eclipse (3.1.1) development environment (both debug and normal mode).
If a create a JAR from it, then start it from there (outside Eclipse), I 
have no VM crash.
------------------------------------

Comments
EVALUATION New bug is 6574633 : native printDialog crashes when changing printer
27-06-2007

EVALUATION Will open a new bug id for the non-common case of changing the printer. Marking bug back to "fix delivered".
27-06-2007

EVALUATION Tested 5.0u11 but it still fails when changing the printer in the print dialog. Not reproducible in 6.0 and latest 7.0.
26-06-2007

SUGGESTED FIX ****************************************************************************************** ** src\windows\native\sun\windows\awt_PrintControl.cpp ****************************************************************************************** BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, jobject printCtrl, PRINTDLG &pd) { HWND hwndOwner = NULL; jobject dialogOwner = env->GetObjectField(printCtrl, AwtPrintControl::dialogOwnerPeerID); if (dialogOwner != NULL) { AwtComponent *dialogOwnerComp = (AwtComponent *)JNI_GET_PDATA(dialogOwner); hwndOwner = dialogOwnerComp->GetHWnd(); env->DeleteLocalRef(dialogOwner); dialogOwner = NULL; } jobject mdh = NULL; jobject dest = NULL; jobject select = NULL; jobject dialog = NULL; LPTSTR printName = NULL; LPTSTR portName = NULL; // If the user didn't specify a printer, then this call returns the // name of the default printer. jstring printerName = (jstring) env->CallObjectMethod(printCtrl, AwtPrintControl::getPrinterID); if (printerName != NULL) { pd.hDevMode = AwtPrintControl::getPrintHDMode(env, printCtrl); pd.hDevNames = AwtPrintControl::getPrintHDName(env, printCtrl); LPTSTR getName = (LPTSTR)JNU_GetStringPlatformChars(env, printerName, NULL); BOOL samePrinter = FALSE; // check if given printername is same as the currently saved printer if (pd.hDevNames != NULL ) { DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(pd.hDevNames); if (devnames != NULL) { LPTSTR lpdevnames = (LPTSTR)devnames; printName = lpdevnames+devnames->wDeviceOffset; if (!_tcscmp(printName, getName)) { samePrinter = TRUE; printName = _tcsdup(lpdevnames+devnames->wDeviceOffset); portName = _tcsdup(lpdevnames+devnames->wOutputOffset); } } //{FIX ::GlobalUnlock(pd.hDevNames); //}FIX } .... ****************************************************************************************** ** src\windows\native\sun\windows\awt_PrintControl.cpp ****************************************************************************************** BOOL AwtPrintControl::UpdateAttributes(JNIEnv *env, jobject printCtrl, PRINTDLG &pd) { HGLOBAL oldG = AwtPrintControl::getPrintHDMode(env, printCtrl); if (pd.hDevMode != oldG) { //{FIX // if (oldG != NULL) { // ::GlobalFree(oldG); // } //}FIX AwtPrintControl::setPrintHDMode(env, printCtrl, pd.hDevMode); } oldG = AwtPrintControl::getPrintHDName(env, printCtrl); if (pd.hDevNames != oldG) { //{FIX // if (oldG != NULL) { // ::GlobalFree(oldG); // } //}FIX AwtPrintControl::setPrintHDName(env, printCtrl, pd.hDevNames); } DEVNAMES *devnames = NULL; DEVMODE *devmode = NULL; unsigned int copies = 1; DWORD pdFlags = pd.Flags; DWORD dmFields; bool newDC = false; if (pd.hDevMode != NULL) { devmode = (DEVMODE *)::GlobalLock(pd.hDevMode); DASSERT(!IsBadReadPtr(devmode, sizeof(DEVMODE))); if (devmode != NULL) { dmFields = devmode->dmFields; if (devmode->dmFields & DM_COPIES) { copies = devmode->dmCopies; if (pd.nCopies == 1) { env->SetBooleanField(printCtrl, driverDoesMultipleCopiesID, JNI_TRUE); } else { copies = pd.nCopies; } } if (devmode->dmFields & DM_PAPERSIZE) { env->CallVoidMethod(printCtrl, AwtPrintControl::setWin32MediaID, devmode->dmPaperSize, devmode->dmPaperWidth, devmode->dmPaperLength); } if (devmode->dmFields & DM_COLOR) { if (devmode->dmColor == DMCOLOR_COLOR) { dmFields |= SET_COLOR; } else { dmFields &= ~SET_COLOR; } } if (devmode->dmFields & DM_ORIENTATION) { if (devmode->dmOrientation == DMORIENT_LANDSCAPE) { dmFields |= SET_ORIENTATION; } else { dmFields &= ~SET_ORIENTATION; } } if (devmode->dmFields & DM_COLLATE) { if (devmode->dmCollate == DMCOLLATE_TRUE) { pdFlags |= PD_COLLATE; env->SetBooleanField(printCtrl, driverDoesCollationID, JNI_TRUE); } else { pdFlags &= ~PD_COLLATE; } } if (devmode->dmFields & DM_PRINTQUALITY) { if (devmode->dmPrintQuality == DMRES_HIGH) { dmFields |= SET_RES_HIGH; } else if ((devmode->dmPrintQuality == DMRES_LOW) || (devmode->dmPrintQuality == DMRES_DRAFT)) { dmFields |= SET_RES_LOW; } else if (devmode->dmPrintQuality == DMRES_MEDIUM) { dmFields &= ~(SET_RES_HIGH | SET_RES_LOW); } else { int xRes = devmode->dmPrintQuality; int yRes = (devmode->dmFields & DM_YRESOLUTION) ? devmode->dmYResolution : devmode->dmPrintQuality; env->CallVoidMethod(printCtrl, AwtPrintControl::setResID, xRes, yRes); dmFields &= ~DM_PRINTQUALITY; } } if (devmode->dmFields & DM_DUPLEX) { if (devmode->dmDuplex == DMDUP_HORIZONTAL) { dmFields |= SET_DUP_HORIZONTAL; } else if (devmode->dmDuplex == DMDUP_VERTICAL) { dmFields |= SET_DUP_VERTICAL; } else { dmFields &= ~(SET_DUP_HORIZONTAL | SET_DUP_VERTICAL); } } devmode = NULL; } else { copies = pd.nCopies; } ::GlobalUnlock(pd.hDevMode); } if (pd.hDevNames != NULL) { DEVNAMES *devnames = (DEVNAMES*)::GlobalLock(pd.hDevNames); DASSERT(!IsBadReadPtr(devnames, sizeof(DEVNAMES))); LPTSTR lpcNames = (LPTSTR)devnames; LPTSTR pbuf = (_tcslen(lpcNames + devnames->wDeviceOffset) == 0 ? TEXT("") : lpcNames + devnames->wDeviceOffset); if (pbuf != NULL) { jstring jstr = JNU_NewStringPlatform(env, pbuf); env->CallVoidMethod(printCtrl, AwtPrintControl::setPrinterID, jstr); env->DeleteLocalRef(jstr); } ::GlobalUnlock(pd.hDevNames); devnames = NULL; } env->CallVoidMethod(printCtrl, AwtPrintControl::setNativeAttID, pdFlags, dmFields); // copies & range are always set so no need to check for any flags env->CallVoidMethod(printCtrl, AwtPrintControl::setRangeCopiesID, pd.nFromPage, pd.nToPage, (pdFlags & PD_PAGENUMS), copies); // repeated calls to printDialog should not leak handles HDC oldDC = AwtPrintControl::getPrintDC(env, printCtrl); if (pd.hDC != oldDC) { if (oldDC != NULL) { ::DeleteDC(oldDC); } AwtPrintControl::setPrintDC(env, printCtrl, pd.hDC); newDC = true; } return newDC; } ****************************************************************************************** ** src\windows\native\sun\windows\awt_PrintJob.cpp ****************************************************************************************** JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WPrinterJob_pageSetup (JNIEnv *env, jobject self, jobject page, jobject painter) { TRY; HWND hwndOwner = NULL; jobject dialogOwner = env->GetObjectField(self, AwtPrintControl::dialogOwnerPeerID); if (dialogOwner != NULL) { AwtComponent *dialogOwnerComp = (AwtComponent *)JNI_GET_PDATA(dialogOwner); hwndOwner = dialogOwnerComp->GetHWnd(); env->DeleteLocalRef(dialogOwner); dialogOwner = NULL; } jboolean doIt = JNI_FALSE; // Assume the user will cancel the dialog. PAGESETUPDLG setup; memset(&setup, 0, sizeof(setup)); setup.lStructSize = sizeof(setup); setup.hwndOwner = hwndOwner; setup.hDevMode = NULL; setup.hDevNames = NULL; setup.Flags = PSD_RETURNDEFAULT | PSD_DEFAULTMINMARGINS; // setup.ptPaperSize = // setup.rtMinMargin = // setup.rtMargin = setup.hInstance = NULL; setup.lCustData = 0; setup.lpfnPageSetupHook = reinterpret_cast<LPPAGESETUPHOOK>(pageDlgHook); setup.lpfnPagePaintHook = NULL; setup.lpPageSetupTemplateName = NULL; setup.hPageSetupTemplate = NULL; /* Because the return default flag is set, this first call * will not display the dialog but will return default values, inc * including hDevMode, hDevName, ptPaperSize, and rtMargin values. * We can use the devmode to set the orientation of the page * and the size of the page. * The units used by the user is also needed. */ if (AwtPrintControl::getPrintHDMode(env,self) == NULL || AwtPrintControl::getPrintHDName(env,self) == NULL) { (void)AwtCommDialog::PageSetupDlg(&setup); /* check if hDevMode and hDevNames are set. * If both are null, then there is no default printer. */ if ((setup.hDevMode == NULL) && (setup.hDevNames == NULL)) { return JNI_FALSE; } } else { int measure = PSD_INTHOUSANDTHSOFINCHES; int sz = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, NULL, 0); if (sz > 0) { LPTSTR str = (LPTSTR)safe_Malloc(sizeof(TCHAR) * sz); if (str != NULL) { sz = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE, str, sz); if (sz > 0) { if (_tcscmp(TEXT("0"), str) == 0) { measure = PSD_INHUNDREDTHSOFMILLIMETERS; } } free((LPTSTR)str); } } setup.Flags |= measure; setup.hDevMode = AwtPrintControl::getPrintHDMode(env, self); setup.hDevNames = AwtPrintControl::getPrintHDName(env, self); } /* Move page size and orientation from the PageFormat object * into the Windows setup structure so that the format can * be displayed in the dialog. */ pageFormatToSetup(env, self, page, &setup, AwtPrintControl::getPrintDC(env, self)); setup.lpfnPageSetupHook = reinterpret_cast<LPPAGESETUPHOOK>(pageDlgHook); setup.Flags = PSD_ENABLEPAGESETUPHOOK | PSD_MARGINS; AwtDialog::ModalDisable(NULL); BOOL ret = AwtCommDialog::PageSetupDlg(&setup); AwtDialog::ModalEnable(NULL); AwtDialog::ModalNextWindowToFront(AwtToolkit::GetInstance().GetHWnd()); if (ret) { jobject paper = getPaper(env, page); int units = setup.Flags & PSD_INTHOUSANDTHSOFINCHES ? MM_HIENGLISH : MM_HIMETRIC; POINT paperSize; RECT margins; jboolean isPortrait; /* Get the Windows paper and margins description. */ retrievePaperInfo(&setup, &paperSize, &margins, &isPortrait, AwtPrintControl::getPrintDC(env, self)); /* Convert the Windows' paper and margins description * and place them into a Paper instance. */ setPaperValues(env, paper, &paperSize, &margins, units); /* Put the updated Paper instance and the orientation into * the PageFormat. */ setPaper(env, page, paper); setOrientation(env, page, isPortrait); if (setup.hDevMode != NULL) { DEVMODE *devmode = (DEVMODE *)::GlobalLock(setup.hDevMode); if (devmode != NULL) { if (devmode->dmFields & DM_PAPERSIZE) { setPrintPaperSize(env, self, devmode->dmPaperSize); } } ::GlobalUnlock(setup.hDevMode); } doIt = JNI_TRUE; } HGLOBAL oldG = AwtPrintControl::getPrintHDMode(env, self); if (setup.hDevMode != oldG) { //{FIX // if (oldG != NULL) { // ::GlobalFree(oldG); // } //}FIX AwtPrintControl::setPrintHDMode(env, self, setup.hDevMode); } oldG = AwtPrintControl::getPrintHDName(env, self); if (setup.hDevNames != oldG) { //{FIX // if (oldG != NULL) { // ::GlobalFree(oldG); // } //}FIX AwtPrintControl::setPrintHDName(env, self, setup.hDevNames); } return doIt; CATCH_BAD_ALLOC_RET(0); }
25-10-2006

EVALUATION -------------------------------------------------------------- ATTENTION! To stably reproduce the bug, please turn on "Extend support of advanced text services to all programs". ( On MS XP: 1. Open Control Panel->Regional and Language Options->Lanuages Tab 2. Option "Install files for East Asian languages" has to be on 3. Press "Details..." 4. Choose tab "Advanced" 5. Option "Extend support of advanced text services to all programs" has to be on ) -------------------------------------------------------------- The crash faced by doubled-freed memory bugs in common dialogs. To prove the reason, please rewrite the test example to make it cyclic: ... public void startPrint() { PrinterJob job = PrinterJob.getPrinterJob(); Paper a4Paper = new Paper(); a4Paper.setSize(595, 840); a4Paper.setImageableArea(40, 40, 515, 760); PageFormat pageFormat = job.defaultPage(); pageFormat.setOrientation(PageFormat.PORTRAIT); pageFormat.setPaper(a4Paper); for(int i=0; i<4; ++i){ //pageFormat = job.pageDialog(pageFormat); //job.setPageable(getBook(pageFormat)); job.printDialog(); // <-- crashes the JVM } } ... The crash happened just in case when ���OK��� was pressed. In case of ���Cancel��� everything is working fine. Detailed investigation shown, that functions Java_sun_awt_windows_WPrinterJob_pageSetup (\src\windows\native\sun\windows\awt_PrintJob.cpp) and AwtPrintControl::UpdateAttributes (src\windows\native\sun\windows\awt_PrintControl.cpp) call ::GlobalFree for handlers from getters AwtPrintControl::getPrintHDMode and AwtPrintControl::getPrintHDMode. Citation: HGLOBAL oldG = AwtPrintControl::getPrintHDMode(env, printCtrl); if (pd.hDevMode != oldG) { //{cut if (oldG != NULL) { ::GlobalFree(oldG); } //}cut AwtPrintControl::setPrintHDMode(env, printCtrl, pd.hDevMode); } oldG = AwtPrintControl::getPrintHDName(env, printCtrl); if (pd.hDevNames != oldG) { //{cut if (oldG != NULL) { ::GlobalFree(oldG); } //}cut AwtPrintControl::setPrintHDName(env, printCtrl, pd.hDevNames); } BUT THOSE HANDELS ALREADY RELEASED in PageSetupDlg or PrintDlg native WIN32 common dialogs in ���OK pressed��� method and new handles were written to structures PAGESETUPDLG and PRINTDLG respectively. So we have double-freed memory and corrupted stack. At the first call getters always return NULL for both old handlers and problem does not happen. Fast-and-dirty solution is in removing of code between ���cut��� comments in functions AwtPrintControl::UpdateAttributes and Java_sun_awt_windows_WPrinterJob_pageSetup (look to Suggested Fix). It is fixing 1.5 release, but Java get an access to invalid handles hDevNames and hDevMode for time quant. That is dangerous. The better way is in handlers copy creation for common dialogs structures. WARNING! Pay attention for missed ::GlobalUnlock(pd.hDevNames) in src\windows\native\sun\windows\awt_PrintControl.cpp P.S. IME support in product is a subject for additional discussion. In accordance with my opinion currently we have memory leaks (there are not ImmReleaseContext calls)
25-10-2006

EVALUATION It seems that the problem is in new modality support. The crash happened in stack: ??0?$Interface_RefCnt@UITfDocumentMgr@@@@QAE@PAUITfDocumentMgr@@@Z: 755C4EF5 mov edi,edi 755C4EF7 push ebp 755C4EF8 mov ebp,esp 755C4EFA mov eax,dword ptr [ebp+8] 755C4EFD test eax,eax 755C4EFF push esi 755C4F00 mov esi,ecx 755C4F02 mov dword ptr [esi+4],eax 755C4F05 mov dword ptr [esi],offset Interface_RefCnt<ITfDocumentMgr>::`vftable' (755C1454h) 755C4F0B je Interface_RefCnt<ITfDocumentMgr>::Interface_RefCnt<ITfDocumentMgr>+1Eh (755C4F13h) 755C4F0D mov ecx,dword ptr [eax] <================ C [msctfime.ime+0x4f0d] Interface_RefCnt<ITfDocumentMgr>::Interface_RefCnt<ITfDocumentMgr> C [msctfime.ime+0x5179] Interface_RefCnt<ITfDocumentMgr>::Interface_Attach<ITfDocumentMgr> C [msctfime.ime+0x552b] CicBridge::GetDocumentManager C [msctfime.ime+0x567c] CicBridge::IsDefaultIMCDim C [msctfime.ime+0x62ce] CicBridge::SetAssociate C [msctfime.ime+0x6f7a] CicBridge::SetActiveContextAlways While investigation I could not reproduce the problem.
20-10-2006

EVALUATION Seem the problem has eliminated with a new modal mechanism introduced in JDK6.0b38. It's unlikely that we can backport it into Tiger.
27-03-2006

EVALUATION I took a look at the changes made between Mustang b37 and b38, and found that the following change in awt_PrintJob.cpp has something to do with the problem: --- static UINT CALLBACK pageDlgHook(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { <snip> switch(msg) { case WM_INITDIALOG: { PAGESETUPDLG *psd = (PAGESETUPDLG *)lParam; jobject peer = (jobject)(psd->lCustData); env->CallVoidMethod(peer, AwtPrintDialog::setHWndMID, (jlong)hDlg); SetForegroundWindow(hDlg); break; } --- The piece other than SetForegroundWindow(hDlg) was added with the modal modification. If I remove the added portion (or simulate it by passing '0' to CallVoidMethod() instead of 'hDlg'), the problem is reproducible. So I am transferring this bug to the AWT team.
25-03-2006

WORK AROUND Control Panel->Regional and Language Options->Lanuages Tab-> Pressed "Details..." to bring up the "Text Services and Input Languages" dialog and there select the "Advanced" tab and CLEAR the option to "Extend support of advanced text services to all programs".
20-03-2006

EVALUATION So the clue to what is going on here is in the stack trace : >C [msctfime.ime+0x4f0d] This is crashing in a Microsoft library related to text services such as input method support. This should only be seen in the stack trace if this has been enabled by some mechanism. In the cases that have come to light so far this is when the user has gone into Control Panel->Regional and Language Options->Lanuages Tab-> Pressed "Details..." to bring up the "Text Services and Input Languages" dialog and there selected the "Advanced" tab and ticked/selected the option to "Extend support of advanced text services to all programs". This option is (I think) available only if you have installed such services. Using the attached test case bug manifests for after the print dialog is hidden when I click in the dos window that initiated the test case. Furthermore the bug disappears in mustang b38. There's a fair number of changes in that build including a large number of AWT modal dialog fixes but one other bug fix stands out : 6252674 : WinXP: Language bar got turned off (disappeared from desktop) after switching to java input method Looking at this, the reason it fixes is probably that it is careful to maintain a handle to the default status window associated with the toolkit thread and opens/closes it as needed. The previous fix always hid it. So it looks like previously the code could ask windows to hide something that was already hidden, but precisely what is going on would require some careful study by someone familiar with the way all this works. Also this crashing bug is very reproducible on 1.5. update 7, however by commenting out the calls to WInputMethod. enableNativeIME and disableNativeIME cured the crash. So it seems this is the issue. Also this stack trace is remarkably familiar to the crash we saw on Vista with 1.5. update 7 : 6395356 : Crash when printing to a file using native print dialog on Vista So printing to a file probably wasn't the issue so much as bringing up two dialogs .. and this might also explain why the Swing dialog wasn't affected. It seems likely that on Vista these text services are on by default.
20-03-2006