From: Kenneth J.Davis (jeremyd@computer.org)
Date: Tue Mar 26 2002 - 20:31:39 EST
Hello,
I have been looking into this bug and while I don't claim
this is correct, so far I believe the problem is related to
XAP_Frame's autoSaveTimer and the assumption that an UT_Timer's
id is unique and nonchanging. As best as I can tell, XAP_Frame
creates the autoSaveTimer, stores its id, and later delete's
the timer, using this id. The problem is the Win32 implementation
of UT_Timer will change its id if the window handle is NULL and
a newly created UT_Timer may reuse the old id. I'm not saying this is
what happens, but it appears that in fl_DocLayout.cpp, a
m_pRedrawUpdateTimer is being created that has the same id as
what XAP_Frame thinks its autoSaveTimer id is and XAP_Frame is
deleting the timer before fl_DocLayout (at least making sure
the two can never get the same value prevents the problem).
I could be wrong, but three things I have tried that fix* the problem
seem to suggest this.
Really bad hack (potentially not 100% reliable and may actually
be reading free'd memory), in fl_DocLayout.cpp, only perform the
the delete if you can find the Timer
if (m_pRedrawUpdateTimer->findTimer(m_pRedrawUpdateTimer->getIdentifier()) != NULL)
(note that if the timer is valid, this should always be true [or am I wrong?],
but if the timer is invalid it could also return true (though usually will be false))
Alternate bad hack (makes the problem go away, but not really
a fix) is in UT_Win32Timer.cpp, in _createIdentifier(void),
change the way it returns ids, eg add +1 if we would otherwise
return _getVecTimers().getItemCount() or simply return an
ever increasing value.
What I believe actually fixes this particular problem, but
leaves the possibility of other such issues, in XAP_Frame change
all uses of m_iIdAutoSaveTimer from an UT_Timer's identifier
to a pointer to the actual UT_Timer. This makes the problem
go away (no longer tried to delete an invalid m_pRedrawUpdateTimer),
and prevents some unable to find timer [X] messages (within XAP_Frame).
If my assumptions are correct, then this is a fix, otherwise it
is simply changing memory layout so something else is corrupted.
I believe a proper fix is to make sure the UT_Win32Timer
returns a unique and nonchanging id. I have an idea of how to
do this. But I'm open to suggestions, as they will probably be
simpler and better than what I'm considering; or if you think
I'm incorrect on this issue, let me know what you think the cause is
or suggestions to try to better isolate the cause. Right now the
crash occurs when attempting to delete a non NULL m_pRedrawUpdateTimer,
which definitely has the wrong id from any Timer's in the static
vector of timers (it appears to be pointing to already free'd
memory, though this is based on intuition and not fact).
Anyway, I'll see about making a proper patch tommorrow (assuming
the bug still appears -- I wish I had a memory debugger/checker for Win32).
Thank you,
Jeremy Davis
jeremyd@computer.org
This archive was generated by hypermail 2.1.4 : Tue Mar 26 2002 - 21:49:36 EST