Tcl Source Code

View Ticket
Login
Ticket UUID: 3081065
Title: post-free writes to Tcl_Obj fields
Type: Bug Version: obsolete: 8.6b1.1
Submitter: dgp Created on: 2010-10-04 18:25:22
Subsystem: 47. Bytecode Compiler Assigned To: dgp
Priority: 9 Immediate Severity:
Status: Closed Last Modified: 2010-10-07 10:06:31
Resolution: Fixed Closed By: dgp
    Closed on: 2010-10-07 03:06:31
Description:
Tcl HEAD:

$ make test TESTFLAGS='-singleproc 1 -file "http.test httpold.test"'
...
http.test
Running httpd in thread 1080544144
httpold.test
Running http 1.0 tests in slave interp
httpold.test:   Total   31      Passed  31      Skipped 0       Failed  0
make: *** [test-tcl] Segmentation fault

segfault after [tcltest::cleanupTests] returns.
User Comments: dgp added on 2010-10-07 10:06:31:

allow_comments - 1

dgp added on 2010-10-07 10:06:29:
Good observation.  Miguel and I 
are already pursuing that as a separate
issue.  See 467523 and

http://paste.tclers.tk/2216

FreeExprCodeInternalRep is the other
which matches the pattern, and I'll be
changing it as well, though current other
choices in expr compilation are such that
an analogous bug "can't happen".

nijtmans added on 2010-10-07 04:06:53:

File Added - 389100: tclCompile.patch

nijtmans added on 2010-10-07 04:05:01:

allow_comments - 0

nijtmans added on 2010-10-07 04:05:00:
Two minor observations:
- If this can happen in FreeSubstCodeInternalRep, then
it can happen in FreeByteCodeInternalRep as well.
- After modifying FreeByteCodeInternalRep, it's
implementation is equal to FreeSubstCodeInternalRep,
so one of them could be eliminated.

I don't know if a test case can be found for this,
but better safe than sorry. Here is a patch. The
FreeByteCodeInternalRep change should be
backported to 8.5 and 8.4 as well IMHO.

dgp added on 2010-10-07 01:39:12:

allow_comments - 1

Committed.

dgp added on 2010-10-07 01:24:19:
Attached is a fix with test.

dgp added on 2010-10-07 01:23:01:

File Added - 389085: 3081065.patch

dgp added on 2010-10-05 23:30:13:
When calling TclCleanupByteCode()
to free the internal rep of a Tcl_Obj, it is
possible to reduce the refcount on that same
Tcl_Obj to zero, causing it to be freed.  This
means a freeIntRepProc ought not be writing
to the objPtr->fields after TCBC returns.

dgp added on 2010-10-05 20:20:30:

File Added - 388895: demo.tcl

dgp added on 2010-10-05 20:19:47:
Attached is a demo script.

The crash is in MoveObjs in the
thread-enabled allocator.  The chain
of Tcl_Obj's is corrupted with a NULL
value where a link in the chain ought
to be.

Suspect the real cause must be something
continuing to write NULLs to an intrep after
the Tcl_Obj has been freed.  The <substcode>
Tcl_ObjType is a likely suspect, but not yet
confirmed.

kennykb added on 2010-10-05 03:41:24:
Stack trace:

==24462== Invalid read of size 4
==24462==    at 0x4137C32: MoveObjs (tclThreadAlloc.c:719)
==24462==    by 0x413794F: TclThreadFreeObj (tclThreadAlloc.c:630)
==24462==    by 0x4115C3E: TclFreeObj (tclObj.c:1447)
==24462==    by 0x414AA06: DeleteArray (tclVar.c:5430)
==24462==    by 0x414649E: UnsetVarStruct (tclVar.c:2532)
==24462==    by 0x414A69F: TclDeleteNamespaceVars (tclVar.c:5253)
==24462==    by 0x410F89E: TclTeardownNamespace (tclNamesp.c:1053)
==24462==    by 0x4052B0B: DeleteInterpProc (tclBasic.c:1419)
==24462==    by 0x4125AF8: Tcl_EventuallyFree (tclPreserve.c:299)
==24462==    by 0x4052944: Tcl_DeleteInterp (tclBasic.c:1308)
==24462==    by 0x40E8DEE: SlaveObjCmdDeleteProc (tclInterp.c:2587)
==24462==    by 0x4054A41: Tcl_DeleteCommandFromToken (tclBasic.c:3021)
==24462==  Address 0x10 is not stack'd, malloc'd or (recently) free'd

msofer added on 2010-10-05 02:35:09:
no repro here, and valgrind looks happy enough

dgp added on 2010-10-05 01:33:27:
Narrowing it down, same segfault from:

make test TESTFLAGS='-singleproc 1 -file "http.test httpold.test" -match httpold-5.1'

so only one test is run.

Attachments: