United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4870762 : Regression: 1.4.1_0x JVM crash in native code during drag and drop operation

Details
Type:
Bug
Submit Date:
2003-05-28
Status:
Resolved
Updated Date:
2003-07-21
Project Name:
JDK
Resolved Date:
2003-06-18
Component:
client-libs
OS:
windows_2000
Sub-Component:
java.awt
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
1.4.1_03,1.4.2
Fixed Versions:
1.4.1_05 (05)

Related Reports
Backport:
Backport:
Duplicate:

Sub Tasks

Description
Customer Problem Description:
---------------------------------

>Yes, it happens on 1.4.1_03 (b02) JVM (FCS bits). It's been in there at 
>least since 1.4.1-b21, possibly much longer.
>
>It's a VM crash when certain objects are dragged onto a Swing window. I 
>have two repro cases, both with the same source code. It repros every 
>time, on my machine and several other test machines.
>
>First, compile the attached DnDRepro.java (javac DnDRepro.java). Run two 
>instances (java -cp . DnDRepro) at the same time. Click in the gray part 
>of the window in one instance and drag to the other instance. The VM 
>that's being dragged onto crashes. Crash dump attached 

>Second, run a single instance. Drag a contact from MSN Messenger onto the 
>window (tested with version 4.7.2009, but has happened with other version 
>as well). The VM will crash. Crash dump attached

>There are probably many more drag sources that will crash the VM, but I 
>haven't done an exhaustive search.

An unexpected exception has been detected in native code outside the VM.
Unexpected Signal : EXCEPTION_ACCESS_VIOLATION occurred at PC=0x64002E
Function=[Unknown.]
Library=(N/A)

NOTE: We are unable to locate the function name symbol for the error
      just occurred. Please refer to release documentation for possible
      reason and solutions.


Current Java thread:
        at sun.awt.windows.WToolkit.eventLoop(Native Method)
        at sun.awt.windows.WToolkit.run(WToolkit.java:253)
        at java.lang.Thread.run(Thread.java:536)

Dynamic libraries:
0x00400000 - 0x00406000         D:\depot\v2\build\jdk1.4.1_03\bin\java.exe
0x77F50000 - 0x77FF7000         C:\WINDOWS\System32\ntdll.dll
0x77E60000 - 0x77F46000         C:\WINDOWS\system32\kernel32.dll
0x77DD0000 - 0x77E5D000         C:\WINDOWS\system32\ADVAPI32.dll
0x78000000 - 0x7807F000         C:\WINDOWS\system32\RPCRT4.dll
0x77C10000 - 0x77C63000         C:\WINDOWS\system32\MSVCRT.dll
0x6D340000 - 0x6D46B000         D:\depot\v2\build\jdk1.4.1_03\jre\bin\client\jvm.dll
0x77D40000 - 0x77DC6000         C:\WINDOWS\system32\USER32.dll
0x77C70000 - 0x77CB0000         C:\WINDOWS\system32\GDI32.dll
0x76B40000 - 0x76B6C000         C:\WINDOWS\System32\WINMM.dll
0x76390000 - 0x763AC000         C:\WINDOWS\System32\IMM32.DLL
0x629C0000 - 0x629C8000         C:\WINDOWS\System32\LPK.DLL
0x72FA0000 - 0x72FFA000         C:\WINDOWS\System32\USP10.dll
0x6D1E0000 - 0x6D1E7000         D:\depot\v2\build\jdk1.4.1_03\jre\bin\hpi.dll
0x6D310000 - 0x6D31E000         D:\depot\v2\build\jdk1.4.1_03\jre\bin\verify.dll
0x6D220000 - 0x6D239000         D:\depot\v2\build\jdk1.4.1_03\jre\bin\java.dll
0x6D330000 - 0x6D33D000         D:\depot\v2\build\jdk1.4.1_03\jre\bin\zip.dll
0x6D000000 - 0x6D105000         D:\depot\v2\build\jdk1.4.1_03\jre\bin\awt.dll
0x73000000 - 0x73023000         C:\WINDOWS\System32\WINSPOOL.DRV
0x771B0000 - 0x772D1000         C:\WINDOWS\system32\ole32.dll
0x5AD70000 - 0x5ADA4000         C:\WINDOWS\System32\uxtheme.dll
0x6D190000 - 0x6D1E0000         D:\depot\v2\build\jdk1.4.1_03\jre\bin\fontmanager.dll
0x73760000 - 0x737A4000         C:\WINDOWS\System32\ddraw.dll
0x73BC0000 - 0x73BC6000         C:\WINDOWS\System32\DCIMAN32.dll
0x73940000 - 0x73A07000         C:\WINDOWS\System32\D3DIM700.DLL
0x17730000 - 0x1773D000         C:\WINDOWS\System32\tabhook.dll
0x17860000 - 0x1788B000         C:\WINDOWS\System32\msctfime.ime
0x746F0000 - 0x74716000         C:\WINDOWS\System32\Msimtf.dll
0x74720000 - 0x74764000         C:\WINDOWS\System32\MSCTF.dll
0x179B0000 - 0x179ED000         C:\Program Files\Network Associates\VirusScan\Wbhook32.dll
0x77C00000 - 0x77C07000         C:\WINDOWS\system32\VERSION.dll
0x17B00000 - 0x17B09000         C:\Program Files\Network Associates\VirusScan\Res09\WbhkRes.dll
0x17B10000 - 0x17B34000         C:\Program Files\Trillian\events.dll
0x77340000 - 0x773CB000         C:\WINDOWS\system32\COMCTL32.dll
0x763B0000 - 0x763F5000         C:\WINDOWS\system32\comdlg32.dll
0x70A70000 - 0x70AD4000         C:\WINDOWS\system32\SHLWAPI.dll
0x773D0000 - 0x77BC2000         C:\WINDOWS\system32\SHELL32.dll
0x71950000 - 0x71A34000         C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.10.0_x-ww_f7fb5805\comctl32.dll
0x76C90000 - 0x76CB2000         C:\WINDOWS\system32\imagehlp.dll
0x6D510000 - 0x6D58D000         C:\WINDOWS\system32\DBGHELP.dll
0x76BF0000 - 0x76BFB000         C:\WINDOWS\System32\PSAPI.DLL

Local Time = Tue May 27 15:40:04 2003
Elapsed Time = 18
#
# The exception above was detected in native code outside the VM
#
# Java VM: Java HotSpot(TM) Client VM (1.4.1_03-b02 mixed mode)
#

                                    

Comments
EVALUATION

Commit to fix in Tiger (escalation).  
###@###.### 2003-05-30

The data object (IDataObject ) is getting currupted during 
AwtDropTarget::DragOver() call. Need to look into it.
The native stack is dumped in comments section.

###@###.### 2003-05-30

Name: dsR10078			Date: 06/02/2003


The crash happens on an attempt to dereference a dangling pointer to 
a destroyed IDataObject. 

We cache the pointer to the IDataObject passed from the drag source,
but don't cleanup the cache properly in all cases. 

###@###.### 2003-06-02

======================================================================

Found a potential fix. In AwtDropTarget::LoadCache() of awt_DnDDT.cpp,
when the EnumFormatEtc windows api returns an error (other than S_OK),
we forgot to clear the sm_pCurrentDnDDataObject member of AwtDropTarget.
Adding a call to SetCurrentDnDDataObject(NULL) fixes the problem.
See suggested fix for details.
###@###.### 2003-06-02

Name: dsR10078			Date: 06/04/2003


The drag source created in the test case exports the single data flavor for
the drag operation. This data flavor cannot be translated to any
native data format by the Java Data Transfer subsystem, so no native
formats are exported for the drag operations initiated by the test
case.

When no native formats are exported, our implementation of IDataObject
still provides a valid IEnumFormatEtc object when
IDataObject::EnumFormatEtc is called and returns S_OK.

When the drop target invokes EnumFormatEtc on the IDataObject provided
by the Windows OLE subsystem, it should provide the enumerator object
as specified by the drag source.

However if the enumerator is empty (no native data formats are
exported by the drag source) the Windows OLE subsystem returns
E_OUTOFMEMORY.

The Java DnD subsystem incorrectly handles the situation when
IDataObject::EnumFormatEtc returns failure, so that our cache remains
in an inconsistent state:
1.The cached reference to the IDataObject is not cleared properly, so
when this object is destroyed, an attempt to dereference this danging 
pointer causes crash.
2.The reference to an array of formats supported by the drag source is
null, while it should reference an empty array if we failed to get the
list of supported formats. The reference to this array is passed to
the Java Data Transfer subsystem, that assumes it is non-null and
dereferences it. Thus, the inconsistentcy results in NPE if the
DropTarget in a Java application requests the list of supported
flavors.

###@###.### 2003-06-03

======================================================================
                                     
2003-06-03
SUGGESTED FIX

------- awt_DnDDT.cpp -------
*** /tmp/domaWAA        Mon Jun  2 15:35:11 2003
--- awt_DnDDT.cpp       Mon Jun  2 15:30:20 2003
***************
*** 781,786 ****
--- 781,787 ----
          m_dataObject->Release();
          m_dataObject    = (IDataObject*)NULL;
          m_enumFormatEtc = (IEnumFORMATETC*)NULL;
+         SetCurrentDnDDataObject(NULL);
          return;
      }
###@###.### 2003-06-02

Name: dsR10078			Date: 06/04/2003


Complete cache update even if the failure is detected.
This solution fixes both problems: the crash and the exception.
Don't keep a reference to the IEnumFormatEtc object, since it
unnecessarily complicates the code.

--- awt_DnDDT.h	Wed Jun  4 10:54:50 2003
***************
*** 135,141 ****
  	// external COM references
  
  	IDataObject    __RPC_FAR *m_dataObject;
- 	IEnumFORMATETC __RPC_FAR *m_enumFormatEtc;
  
  	// static members
  
--- 135,140 ----

--- awt_DnDDT.cpp	Wed Jun  4 11:42:48 2003
***************
*** 44,50 ****
      m_target	    = env->NewGlobalRef(component->GetTarget(env));
      m_registered    = 0;
      m_dataObject    = NULL;
-     m_enumFormatEtc = NULL;
      m_formats	    = NULL;
      m_nformats	    = 0;
      m_dtcp    	    = NULL;
--- 44,49 ----
***************
*** 766,771 ****
--- 765,771 ----
      JNIEnv*      env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
      unsigned int cnt = 0;
      HRESULT  	 res;
+     IEnumFORMATETC* pEnumFormatEtc = NULL;
  
      if (m_dataObject != (IDataObject*)NULL) UnloadCache();
  
***************
*** 775,795 ****
  
      (m_dataObject = pDataObj)->AddRef();
  
!     res = m_dataObject->EnumFormatEtc(DATADIR_GET, &m_enumFormatEtc);
  
!     if (res != S_OK) {
!         m_dataObject->Release();
!         m_dataObject    = (IDataObject*)NULL;
!         m_enumFormatEtc = (IEnumFORMATETC*)NULL;
!         return;
!     }
! 
      for (;;) {
  	
  	FORMATETC tmp;
  	ULONG	  actual = 1;
  
! 	res = m_enumFormatEtc->Next((ULONG)1, &tmp, &actual);
  
  	if (res == S_FALSE) break;
  
--- 775,789 ----
  
      (m_dataObject = pDataObj)->AddRef();
  
!     res = m_dataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormatEtc);
  
!     if (res == S_OK) {
          for (;;) {
  
              FORMATETC tmp;
              ULONG          actual = 1;
  
!             res = pEnumFormatEtc->Next((ULONG)1, &tmp, &actual);
  
              if (res == S_FALSE) break;
  
***************
*** 820,825 ****
--- 814,823 ----
              m_nformats++;
          }
  
+         // We are responsible for releasing the enumerator.
+         pEnumFormatEtc->Release();
+     }
+ 
      if (m_nformats > 0) {
  	qsort((void*)m_formats, m_nformats, sizeof(FORMATETC),
  	      AwtDropTarget::_compar);
***************
*** 862,870 ****
      env->DeleteGlobalRef(m_cfFormats);
      m_cfFormats = NULL;
  
-     m_enumFormatEtc->Release();
-     m_enumFormatEtc = (IEnumFORMATETC*)NULL;
- 
      if (!IsLocalDnD()) {
  	DASSERT(IsCurrentDnDDataObject(m_dataObject));
  	SetCurrentDnDDataObject(NULL);
--- 860,865 ----

###@###.### 2003-06-05

======================================================================
                                     
2003-06-05
WORK AROUND

We haven't found a workaround for this. You can prevent the VM that's being dragged onto from crashing by making changes to the drag originator, but that doesn't help us since we don't control what's dragged onto our VM. If you discover a workaround, we would be interested.
                                     
2004-06-11
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
1.4.1_05
1.4.2_02
tiger

FIXED IN:
1.4.1_05
1.4.2_02
tiger

INTEGRATED IN:
1.4.1_05
1.4.2_02
tiger
tiger-b11


                                     
2004-06-14



Hardware and Software, Engineered to Work Together