Tcl Source Code

View Ticket
Login
Ticket UUID: 673714
Title: Tcl_DeleteEvents() bug when deleting last event in queue
Type: Bug Version: obsolete: 8.4.1
Submitter: nobody Created on: 2003-01-24 00:27:45
Subsystem: 01. Notifier Assigned To: kennykb
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2003-02-16 03:35:18
Resolution: Fixed Closed By: kennykb
    Closed on: 2003-02-15 20:35:18
Description:
Hello Support,

tclNotify.c : Tcl_DeleteEvents() removes events from
the event queue.  If the event deleted is the last
event in the queue, the tsdPtr->lastEventPtr is left
pointing at evPtr which gets freed.  This leaves
lastEventPtr pointing to freed memory which causes
unpredictable behavior.

I've changed the code so that lastEventPtr (and
markEventPtr) get fixed up correctly in all cases.
New code is included below.

Platform: All
Tested on Solaris 5.6 and Linux 7.1
Tested with Tcl 8.3.4, but same problem exists in
source code is in 8.4.1.

Regards,
Michael Webb
Model Technology Inc.
(503)526-1660
[email protected]


New Code for Tcl_DeleteEvents():

void
Tcl_DeleteEvents(proc, clientData)
    Tcl_EventDeleteProc *proc;      /* The procedure to
call. */
    ClientData clientData;          /* type-specific
data. */
{
    Tcl_Event *evPtr, *prevPtr, *hold;
    ThreadSpecificData *tsdPtr =
TCL_TSD_INIT(&dataKey);
 
    Tcl_MutexLock(&(tsdPtr->queueMutex));
    for (prevPtr = (Tcl_Event *) NULL, evPtr =
tsdPtr->firstEventPtr;
             evPtr != (Tcl_Event *) NULL;
             ) {
        if ((*proc) (evPtr, clientData) == 1) {
            if (tsdPtr->firstEventPtr == evPtr) {
                tsdPtr->firstEventPtr = evPtr->nextPtr;
            } else {
                prevPtr->nextPtr = evPtr->nextPtr;
            }
            if (evPtr->nextPtr == (Tcl_Event *) NULL) {
                tsdPtr->lastEventPtr = prevPtr;
            }
            if (tsdPtr->markerEventPtr == evPtr) {
                tsdPtr->markerEventPtr = prevPtr;
            }
            hold = evPtr;
            evPtr = evPtr->nextPtr;
            ckfree((char *) hold);
        } else {
            prevPtr = evPtr;
            evPtr = evPtr->nextPtr;
        }
    }
    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
}
User Comments: kennykb added on 2003-02-16 03:35:18:
Logged In: YES 
user_id=99768

Fix committed. Fix adds a new 'testevent' command to tclTest.c
and a new 'notify.test' with 23 new test cases to attempt to catch
problems of this type on regression test.

kennykb added on 2003-02-02 05:12:40:

File Added - 41271: 673714.patch

Logged In: YES 
user_id=99768

Submitter's code converted to a patch and attached.
Current tests continue to pass with patch applied.
We need to think up a regression test for this one.

Attachments: