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.
|
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
======================================================================
|
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
======================================================================
|