Issue 19278 - OLE in OLE: On Close the object is disposed and then saved
OLE in OLE: On Close the object is disposed and then saved
Product: General
Classification: Code
Component: code
OOo 1.1 RC4
PC Windows XP
: P2 trivial (vote)
: OOo 1.1.1
Assigned To: frank
Depends on:
  Show dependency treegraph
Reported: 2003-09-08 17:46 UTC by bjoern.milcke
Modified: 2004-01-19 14:48 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Latest Confirmation on: ---
Developer Difficulty: ---

Writer containing a Calc OLE that contains a Chart OLE (11.39 KB, application/octet-stream)
2003-09-08 17:48 UTC, bjoern.milcke
no flags Details

Note You need to log in before you can comment on or make changes to this issue.
Description bjoern.milcke 2003-09-08 17:46:30 UTC
Load the attachment or

1. Create a Calc document with a Chart/Writer/Draw OLE.
2. Save it
3. Create a Writer document. Insert the document created before as OLE-object
(Insert/Object/OLE/Create From File)
4. Save the Writer document
5. Reopen


6. Activate the OLE-object
7. Resize the inner OLE-object
8. Deactivate the OLE-object
9. Delete the OLE-object
=> GPF

The symptom of the GPF is also a thing we should track: In xmloff there are
several member-pointers to ref-counted UNO-objects. In the DTOR of SvXMLExport
an XEventListener with ref-count 0 is used for unregistering (Sascha: it looks
like the last code there was committed by you).

However the root-cause seems to be different. This is what I found out (when
using a Chart OLE as inner OLE), and where I got stuck in investigation:

In Step 9., first a dispose() at the chart's XModel is called, afterwards a
Save() at the SchChartDocShell is called which fails because of the disposed object.

Both stacks have a common part.  It starts with a DoClose() call at the Calc OLE
object from Writer (which obviously is used to save the OLE object)

(sw) BOOL SwOLENode::SavePersistentData()
	if( aOLEObj.pOLERef && aOLEObj.pOLERef->Is() )
		SvPersist* p = GetDoc()->GetPersist();
		if( p )		// muss da sein
			SvInfoObjectRef aRef( p->Find( aOLEObj.aName ) );
			if( aRef.Is() )
				aRef->SetDeleted( TRUE );

=>		(*aOLEObj.pOLERef)->DoClose();

This results in a Close() call at the SvEmbeddedObject, where the two stacks
(below) branch.  First a DoClose() is called which finally results in the
dispose() call.

(so3) BOOL SvEmbeddedObject::Close()
	const SvInfoObjectMemberList * pChildList = GetObjectList();
	if( pChildList )
		ULONG nCount = pChildList->Count();
		for( ULONG i = 0; i < nCount; i++ )
			SvInfoObject * pIO = pChildList->GetObject( i );
			SvPersist * pPer = pIO->GetPersist();
			SvEmbeddedObjectRef xEO( pPer );
			if( xEO.Is() )
(1.) =>			xEO->DoClose();

	// Unter Ole2 muss Close() vor SetClientSite( NULL ) gerufen werden.
(2.) =>	aProt.Reset2Connect();
	// Jetzt SetClientSite( NULL ).
	return TRUE;

Later the Reset2Connect() call requires an Open() of the OLE-object which
results in the SaveObject() call:

(so3) void SvEmbeddedObject::Open( BOOL bOpen )
	String aTest( "Object---Open---" );
	aTest += Owner() ? "Intern" : "Extern: ";
	aTest += bOpen ? "TRUE" : "FALSE";
	DBG_TRACE( aTest )

	// kein Autosave im HandsOff State
	if( bAutoSave && !bOpen && !IsHandsOff())
		SvEmbeddedClient * pCl = GetClient();
		if( pCl )
=>			pCl->SaveObject();


Gathered this information I still cannot decide where the problem lies.  Is
DoClose() the right way to save data, is Open() the right place to save an
object?  Why do we have a problem in this special case but not when there is
only one OLE-chart embedded in a Writer document?


1.	sch645mi.dll!ChXChartDocument::dispose()  Line 1379	C++
 	sfx645mi.dll!SfxBaseModel::close(unsigned char bDeliverOwnership='')  Line
1286 + 0x10	C++
 	sfx645mi.dll!SfxObjectShell::Close()  Line 360 + 0x14	C++
 	sch645mi.dll!SchChartDocShell::Close()  Line 229 + 0xb5	C++
	sot645mi.dll!SotObject::DoClose()  Line 508 + 0xa	C++

2.	sch645mi.dll!SchChartDocShell::Save()  Line 940	C++
 	sfx645mi.dll!SfxObjectShell::DoSave()  Line 930 + 0x25	C++
 	so645mi.dll!SvPersist::SaveChilds()  Line 1823 + 0x1c	C++
 	sfx645mi.dll!SfxInPlaceObject::Save()  Line 234 + 0x1b	C++
 	sc645mi.dll!ScDocShell::Save()  Line 1318	
 	sfx645mi.dll!SfxObjectShell::DoSave()  Line 930 + 0x25	C++
 	so645mi.dll!SvEmbeddedClient::SaveObject()  Line 638 + 0x23	C++
 	so645mi.dll!SvEmbeddedObject::Open(unsigned char bOpen=0)  Line 1059	C++
 	so645mi.dll!SvInPlaceObject::Open(unsigned char bOpen=0)  Line 245	C++
 	sfx645mi.dll!SfxInPlaceObject::Open(unsigned char bOpen=0)  Line 387	C++
 	so645mi.dll!ImplSvEditObjectProtocol::Opened(unsigned char bOpenP=0)  Line 970	C++
 	so645mi.dll!SvEditObjectProtocol::Opened(unsigned char bOpen=0)  Line 990	C++
 	so645mi.dll!SvEmbeddedObject::DoOpen(unsigned char bOpen=0)  Line 784	C++
 	so645mi.dll!ImplSvEditObjectProtocol::Reset2Connect()  Line 716	C++
 	so645mi.dll!SvEditObjectProtocol::Reset2Connect()  Line 730 + 0xa	C++

*: 	so645mi.dll!SvEmbeddedObject::Close()  Line 1025	C++
 	sc645mi.dll!ScDocShell::Close()  Line 214 + 0x53	
 	sot645mi.dll!SotObject::DoClose()  Line 508 + 0xa	C++
 	sw645mi.dll!SwOLENode::SavePersistentData()  Line 229	
 	sw645mi.dll!SwNodes::ChgNode()  Line 311	
 	sw645mi.dll!SwNodes::_MoveNodes()  Line 957	
 	sw645mi.dll!SwUndoSaveCntnt::MoveToUndoNds()  Line 327	
 	sw645mi.dll!SwUndoSaveSection::SaveSection()  Line 783	
 	sw645mi.dll!SwUndoSaveSection::SaveSection()  Line 753	
 	sw645mi.dll!SwUndoFlyBase::DelFly()  Line 250	
 	sw645mi.dll!SwUndoDelLayFmt::SwUndoDelLayFmt()  Line 404	
 	sw645mi.dll!SwDoc::DelLayoutFmt()  Line 437 + 0x19	
 	sw645mi.dll!SwDoc::DeleteSelection()  Line 380	
 	sw645mi.dll!SwDrawView::DeleteMarked()  Line 842 + 0x8	
 	sw645mi.dll!SwFEShell::DelSelectedObj()  Line 2251	
 	sw645mi.dll!SwWrtShell::DelRight()  Line 318	
 	sw645mi.dll!SwBaseShell::ExecDelete()  Line 452	
 	sw645mi.dll!SfxStubSwBaseShellExecDelete()  Line 1655 + 0xf	
 	sfx645mi.dll!SfxDispatcher::Call_Impl()  Line 347 + 0xb	
 	sfx645mi.dll!SfxDispatcher::_Execute()  Line 1077	
Comment 1 bjoern.milcke 2003-09-08 17:48:20 UTC
Created attachment 9095 [details]
Writer containing a Calc OLE that contains a Chart OLE
Comment 2 bjoern.milcke 2003-09-08 17:50:35 UTC
Note, that there is currently a different bug (see Issue 18273) with
OLE-Charts in the scenario, that requires printer dependent layout for
the writer document until fixed.
Comment 3 Mathias_Bauer 2003-10-10 10:11:31 UTC
Don't use an embedded chart for testing, because there is another bug
that let OOo crash even when the file is inserted.
With any other object I always get a crash in the dtor of SvXMLExport.
If you found the root cause it should be discussed wether this bug is
worth to be fixed in OOo1.1.x.
Comment 4 michael.brauer 2003-10-13 09:50:35 UTC
The GPF is caused by the internal bug #111632#. I have to admit that I
don't get from the bug description whether where are other open issues
covered in this task.
Comment 5 Mathias_Bauer 2003-10-13 09:57:20 UTC
Michael thinks that this bug is a duplicate to a crash report you
received. Please check this and then contact Björn to discuss how to
proceed. At least the attached document could be a good bugdoc for
your crash report.
Comment 6 sascha.ballach 2003-10-28 15:07:13 UTC
I take it
Comment 7 sascha.ballach 2003-12-02 15:09:34 UTC
is the same like the internal bug #111624# and so change target

fixed in sab009
Comment 8 sascha.ballach 2003-12-02 15:18:12 UTC
sorry, the internal bug is #111632#
Comment 9 sascha.ballach 2003-12-08 16:19:33 UTC
please verify
Comment 10 frank 2003-12-09 14:54:55 UTC
fixed but failed for Solaris
Comment 11 sascha.ballach 2003-12-10 13:41:39 UTC
fixed, but blocked by another task
Comment 12 sascha.ballach 2003-12-10 13:42:29 UTC
back to you. please verify if the blocking task is fixed
Comment 13 kla 2003-12-19 08:34:42 UTC
Comment 14 kla 2003-12-19 08:35:16 UTC
Comment 15 frank 2004-01-19 14:48:54 UTC
Found integrated in srx645m25s1-1 on Linux, Solaris and Windows