We have a custom Java component that constructs letterheads by mixing
several files and other
data via UNO.
We have encountered several cases where OOo's internal data structures
seem to become
corrupted during the process.

One such issue is the following:

An SwIndexReg (sw/source/core/bastyp/index.cxx) gets destroyed even though there
are still SwIndexes in it. Later, when these SwIndexes are destroyed,
their destructors
call SwIndex::Remove() in an attempt to deregister from the
SwIndexReg. Because the SwIndexReg
has been destroyed, Remove() writes to an invalid memory location,
which can have a variety of
effects, depending on whether and for what the memory has been
allocated again in the meantime.
In one instance that we've observed (and in fact can still reproduce
on one machine),
another SwIndexReg gets allocated at the same memory location as the
destroyed one, causing
SwIndex::Remove() to incorrectly set pFirst and pNext to NULL for the
live SwIndexReg, which
then, much later, causes a segfault due to a NULL-pointer dereference.
It's likely that this issue is responsible for some of the random
crashes people observe with
OOo.

Steps to reproduce:
The following steps will explain how to break with gdb at the point
where the SwIndexReg is
erroneously destroyed (in fact we'll break on the subclass destructor
~SwCntntNode, because
the compiler does not emit code for the empty ~SwIndexReg destructor).
We've tested this on several different machines with OOo 2.1 (debug
build provided by Pavel Janik)
and OOo 2.2 (our own build) and can reproduce the issue 100% of the time.

Unfortunately the
issue only seems to occur when you perform a lot of operations on the
document (which
our custom component does), so we could not distill a minimal testcase.
The only way we know of reproducing the issue is by
installing our letterhead system. You can find it at

http://www.projekt-limux.org/wollmux/

After installing the module according to the instructions on the above page:

0. Terminate all OOo processes and the WollMuxBar
1. Replace your program/libsw680li.so with a copy that contains debug symbols
2. swriter &
3. Wait till writer has finished loading.
4. pgrep soffice.bin
  This gives you the process ID of the soffice.bin process.
5. gdb | tee /tmp/gdb.log

6. set height 0
    This is important because otherwise GDB will wait for a keypress
whenever the
    screen is full and we'll have it produce LOTS of output.

attach <PID of soffice.bin>

  GCC emits multiple destructors and GDB tends to pick the wrong one,
when setting
  a breakpoint with break SwCntntNode::~SwCntntNode(). Setting
breakpoints on the
  mangled names of all the destructor variants works around this problem. Same
  goes for constructors.

break _ZN11SwCntntNodeD0Ev
break _ZN11SwCntntNodeD2Ev
break _ZN11SwCntntNodeD1Ev
break _ZN11SwCntntNodeC2ERK11SwNodeIndexhP9SwFmtColl
break _ZN11SwCntntNodeC1ERK11SwNodeIndexhP9SwFmtColl
break _ZN9SwTxtNodeD2Ev
break _ZN9SwTxtNodeD1Ev
break _ZN9SwTxtNodeD0Ev

commands 5
bt 16
p *this
cont
end

commands 4
bt 16
p *this
cont
end

commands 6
bt 3
cont
end

commands 7
bt 3
cont
end

commands 8
bt 3
cont
end

condition 1 ((struct SwIndexReg*)this)->pFirst != 0
condition 2 ((struct SwIndexReg*)this)->pFirst != 0
condition 3 ((struct SwIndexReg*)this)->pFirst != 0

cont

7. In Writer, use File/Open to open
  
$HOME/.wollmux/wollmux-standard-config/vorlagen/standard/2.Formulare/Abtretungserklärung.ott

8. The template loads and WollMux starts filling in the letterhead.
  GDB produces a lot of output (one backtrace for every SwCntntNode
  that is constructed.)

9. After a (long) while, GDB should stop at one of the conditional breakpoints.
(gdb) bt 16
#0  0x9be08a36 in ~SwCntntNode (this=0x87789a2c)
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/docnode/node.cxx:1069
#1  0x9bd00212 in ~SwTxtNode (this=0x87789a2c)
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/txtnode/ndtxt.cxx:393
#2  0x9be14934 in SwNodes::RemoveNode (this=0x878813d4, nDelPos=10,
nSize=1, bDel=1)
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/docnode/nodes.cxx:2592
#3  0x9be11774 in SwNodes::Delete (this=0x878813d4,
[EMAIL PROTECTED], nNodes=1)
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/docnode/nodes.cxx:1418
#4  0x9bb4666c in ~SwUndoDelete (this=0x86be2da8)
   at /ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/undo/undel.cxx:561
#5  0x9bb4863f in SwUndos::DeleteAndDestroy (this=0x8789b1e8, nP=0, nL=1)
   at /ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/undo/undobj.cxx:110
#6  0x9bb341ea in SwDoc::DelUndoObj (this=0x87881360, nEnde=0)
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/undo/docundo.cxx:337
#7  0x9bb33d41 in SwDoc::AppendUndo (this=0x87881360, pUndo=0x86b776c8)
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/undo/docundo.cxx:239
#8  0x9bd61279 in SwDoc::Insert (this=0x87881360, [EMAIL PROTECTED],
[EMAIL PROTECTED], nFlags=0)
   at /ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/doc/docfmt.cxx:1129
#9  0x9be79d52 in SwXTextField::attachToRange (this=0x86b38914,
[EMAIL PROTECTED])
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/unocore/unofield.cxx:1871
#10 0x9bf210f3 in SwXText::insertTextContent (this=0x87965ca8,
[EMAIL PROTECTED],
   [EMAIL PROTECTED], bAbsorb=1 '\001')
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/unocore/unotext.cxx:621
#11 0x9d5103f8 in ?? () from /opt/openoffice.org2.2/program/libgcc3_uno.so
#12 0x9d51091a in ?? () from /opt/openoffice.org2.2/program/libgcc3_uno.so
#13 0x9d510f5f in ?? () from /opt/openoffice.org2.2/program/libgcc3_uno.so
#14 0x92e61b5c in
Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize ()
  from /opt/openoffice.org2.2/program/libjava_uno.so
#15 0x92e626ec in
Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call ()
  from /opt/openoffice.org2.2/program/libjava_uno.so
(More stack frames follow...)

p *this
$202 = {<SwModify> = {<SwClient> = {_vptr.SwClient = 0x9c40f9a8, pLeft
= 0x87789c20,
     pRight = 0x86bfe6c8, bModifyLocked = 0 '\0', bInModify = 0 '\0',
bInDocDTOR = 0 '\0',
     bInCache = 0 '\0', bInSwFntCache = 0 '\0', pRegisteredIn = 0x87894928},
   pRoot = 0x0}, <SwNode> = {<BigPtrEntry> = {_vptr.BigPtrEntry =
0x9c40f9ec, pBlock = 0x878f9508,
     nOffset = 10}, nNodeType = 8 '\b', nAFmtNumLvl = 0 '\0',
bSetNumLSpace = 0 '\0',
   bIgnoreDontExpand = 0 '\0', pStartOfSection = 0x999521c8}, <SwIndexReg> = {
   _vptr.SwIndexReg = 0x9c40f9fc, pFirst = 0x86b4b9dc, pLast =
0x86b4b9c0, pMiddle = 0x0,
   static pEmptyIndexArray = 0x99940358}, pCondColl = 0x0,
mbSetModifyAtAttr = true, mpAttrSet = {
   px = 0x98b72320, pn = {pi_ = 0x8713ee0c}}}


As you can see, (SwIndexReg*)this->pFirst is non-0, so the object
should not be destroyed.
If you were using a --enable-dbgutil build, you'd get an assertion
failed message from
the ASSERT in ~SwIndexReg().

Now let's look at /tmp/gdb.log for the corresponding constructor call
(i.e. the *last*
call to SwCntntNode() with the same this pointer).

Breakpoint 4, 0x997128d2 in SwCntntNode (this=0x87862af4,
[EMAIL PROTECTED], nNdType=156 '\234',
   pColl=0x87998870) at
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/docnode/node.cxx:1057
1057            : SwNode( rWhere, nNdType ),
#0  0x997128d2 in SwCntntNode (this=0x87862af4, [EMAIL PROTECTED],
nNdType=156 '\234',
   pColl=0x87998870) at
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/docnode/node.cxx:1057
#1  0x99609bbc in SwTxtNode (this=0x87862af4, [EMAIL PROTECTED],
pTxtColl=0x87998870,
   pAutoAttr=0x98b982c0)
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/txtnode/ndtxt.cxx:323
#2  0x9960fe9e in SwTxtNode::_MakeNewTxtNode (this=0x98be012c,
[EMAIL PROTECTED], bNext=0 '\0',
   bChgFollow=0 '\0')
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/txtnode/ndtxt.cxx:2537
#3  0x9960a64b in SwTxtNode::SplitNode (this=0x98be012c, [EMAIL PROTECTED])
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/txtnode/ndtxt.cxx:509
#4  0x99632c58 in SwDoc::SplitNode (this=0x87a5ad60, [EMAIL PROTECTED],
bChkTableStart=false)
   at /ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/doc/doc.cxx:827
#5  0x99a1fd00 in SwXMLImport::startDocument (this=0x87321a44)
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/filter/xml/xmlimp.cxx:799
#6  0x9fe3d0b8 in component_getDescriptionFunc () from
/opt/openoffice.org2.2/program/sax.uno.so
#7  0x99a16c6d in ReadThroughComponent (xInputStream=
       {<com::sun::star::uno::BaseReference> = {_pInterface =
0xa0d871c4}, <No data fields>},
   xModelComponent=
       {<com::sun::star::uno::BaseReference> = {_pInterface =
0x87a601f0}, <No data fields>},
   [EMAIL PROTECTED], [EMAIL PROTECTED],
   pFilterName=0x99cc3d14
"com.sun.star.comp.Writer.XMLOasisContentImporter", rFilterArguments=
     {_pSequence = 0x86ce9070, static s_pType = 0x0}, [EMAIL PROTECTED],
   bMustBeSuccessfull=1 '\001', bEncrypted=0 '\0')
   at /ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/filter/xml/swxml.cxx:301
#8  0x99a1777a in ReadThroughComponent (xStorage=
       {<com::sun::star::uno::BaseReference> = {_pInterface =
0x86cf7a20}, <No data fields>},
   xModelComponent=
       {<com::sun::star::uno::BaseReference> = {_pInterface =
0x87a601f0}, <No data fields>},
   pStreamName=0x99cc3d80 "content.xml",
pCompatibilityStreamName=0x99cc3d74 "Content.xml",
   [EMAIL PROTECTED], pFilterName=0x99cc3d14
"com.sun.star.comp.Writer.XMLOasisContentImporter",
   rFilterArguments={_pSequence = 0x86ce9070, static s_pType = 0x0},
[EMAIL PROTECTED],
   bMustBeSuccessfull=1 '\001')
   at /ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/filter/xml/swxml.cxx:452
#9  0x99a1a957 in XMLReader::Read (this=0x98d09b14, [EMAIL PROTECTED],
[EMAIL PROTECTED],
   [EMAIL PROTECTED], [EMAIL PROTECTED])
   at /ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/filter/xml/swxml.cxx:946
#10 0x9985159f in SwReader::Read (this=0x881c89d8, [EMAIL PROTECTED])
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/filter/basflt/shellio.cxx:303
#11 0x9973bbca in SwUnoCursorHelper::InsertFile (pUnoCrsr=0x87e606cc,
[EMAIL PROTECTED],
   [EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL PROTECTED])
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/unocore/unocrsrhelper.cxx:814
#12 0x997c3f37 in SwXTextCursor::insertDocumentFromURL
(this=0x87985978, [EMAIL PROTECTED],
   [EMAIL PROTECTED])
   at 
/ooo/src-no-SwIndex-patch-O0/OOF680_m11/sw/source/core/unocore/unoobj2.cxx:456


That backtrace goes back to insertDocumentFromURL() and there's no
*Undo* in the call chain,
so to me it seems like the text node in question is unrelated to the
undo information and
I don't see why it would be deleted inside a call to AppendUndo().

This is all I've been able to find out. Note that this is the first
time I've looked at
OOo's code and aside from a few hours I spent debugging this issue I
have no experience with
OOo's internal structures. I've reached the point at which I can't
continue debugging
this issue on my own. I hope someone with a deeper understanding of
the structures involved
will take over. If there's any way I can help, just tell me.

This is an important issue for us, because
almost all of our templates are constructed dynamically in this way
and we're seeing
random crashes for at least some of which this issue is a likely culprit.

Matthias

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

  • [sw-discussion... Matthias B.
    • Re: [sw-d... Frank Meies - Sun Germany - Development - Software Engineer
      • Re: [... Frank Meies - Sun Germany - Development - Software Engineer
        • R... Matthias B.
          • ... Andreas Martens
          • ... Frank Meies - Sun Germany - Development - Software Engineer

Reply via email to