From: Martin Sevior (msevior@mccubbin.ph.unimelb.edu.au)
Date: Tue May 28 2002 - 07:41:50 EDT
On Tue, 28 May 2002, Patrick Lam wrote:
> I've been working on the crashing-endnote-creation-undo bug.
>
> I don't know what to do next; it's as if I'm pretty close to a
> solution but I just need someone else to look at this code and
> give me a useful idea.
>
> THE PROBLEM:
>
> When we create an endnote section, we proceed as follows:
>
> - fv_View.cpp, insertEndnoteSection(const XML_Char ** blkprops, const XML_Char ** blkattrs); lines 7151-...
>
> // Now create the endnotes section
> // First, do a block break to finish the last section.
>
> UT_uint32 iPoint = getPoint();
> m_pDoc->insertStrux(getPoint(), PTX_Block);
>
> // ... snip ...
>
> // Now Insert the endnotes section.
> // Doing things this way will grab the newly inserted block
> // and put into the endnotes section.
>
> m_pDoc->insertStrux(iPoint, PTX_SectionEndnote);
>
> So the PTX_Block strux is created, then the PTX_SectionEndnote strux.
> Great; the piece table and layout classes have a consistent structure.
> The PTX_SectionEndnote contains a pointer to the PTX_Block. Alas!
> the change history is wrong. It contains the instruction to create
> the PTX_Block before the instruction to create the
> PTX_SectionEndnote...
>
> DISASTER:
>
> When we undo, we travel back up the change history. That means that
> the PTX_SectionEndnote is freed, and it contains a pointer to the
> PTX_Block. (More precisely, fl_SectionLayout.cpp:121 is the culprit.)
> It goes ahead and frees the fl_BlockLayout, because it thinks it owns
> this piece of memory.
>
> Unfortunately, the undo proceeds to undo the PTX_Block creation. This
> doesn't work; it's already been freed. The resulting error crashes
> valgrind.
HI Pat,
Yes indeed. I fought hard over this one, I think it works fine for
HdrFtr's at least, all the tests I threw at it came out OK. If you look in
insertHdrFtr ins fv_View you this code:...
m_pDoc->beginUserAtomicGlob(); // Begin the big undo block
// Signal PieceTable Changes have Started
m_pDoc->notifyPieceTableChangeStart();
m_pDoc->disableListUpdates();
insertHeaderFooter(block_props, hfType); // cursor is now in the
header/foo\ter
Then inside insertHeaderFooter you see this....
// change the section to point to the footer which doesn't exist yet.
m_pDoc->changeStruxFmt(PTC_AddFmt, posSec, posSec, sec_attributes2,
NULL, P\TX_Section);
moveInsPtTo(FV_DOCPOS_EOD); // Move to the end, where we will create
the page numbers
// insert the Header/Footer
m_pDoc->insertStrux(getPoint(), PTX_SectionHdrFtr);
m_iInsPoint++;
// Now the block strux for the content
m_pDoc->insertStrux(getPoint(), PTX_Block);
//
// Have to do this coz of the funny state the block is in until the change
strux
//
m_iInsPoint++;
//
// Give the Footer section the properties it needs to attach itself to the
// correct DocSectionLayout.
//
m_pDoc->changeStruxFmt(PTC_AddFmt, getPoint(), getPoint(),
sec_attributes1,\ NULL, PTX_SectionHdrFtr);
// Change the formatting of the new footer appropriately
//(currently just center it)
m_pDoc->changeStruxFmt(PTC_AddFmt, getPoint(), getPoint(), NULL,
props, PTX\_Block);
// OK it's in!
Then wrap it up with an endGlob and your done.
You need the insertStrux block strux right after the endNoteStrux not
before.
Good Luck!
We can talk it over IRC tomorrow if it doesn't work.
Cheers
Martin
This archive was generated by hypermail 2.1.4 : Tue May 28 2002 - 07:46:45 EDT