Tcl Source Code

View Ticket
Login
2015-11-22
08:37 Closed ticket [3d96b7076e]: OO segfault with mem-debug and delayed namespace teardown plus 6 other changes artifact: 6b37a39002 user: dkf
2015-11-21
22:25 Ticket [3d96b7076e]: 6 changes artifact: b381d7c1e6 user: dkf
22:22
[3d96b7076e] Prevent crashes when destroying an object's class inside a method call. check-in: 3a5e60f35a user: dkf tags: trunk
2015-11-19
16:24 Ticket [3d96b7076e] OO segfault with mem-debug and delayed namespace teardown status still Open with 3 other changes artifact: 64c0a5339c user: dgp
16:23 New ticket [3d96b7076e]. artifact: af910dad93 user: dgp

Ticket UUID: 3d96b7076ee08182ee55c6c71cc860a88fae4ab9
Title: OO segfault with mem-debug and delayed namespace teardown
Type: Bug Version: trunk
Submitter: dgp Created on: 2015-11-19 16:23:56
Subsystem: 35. TclOO Package Assigned To: dkf
Priority: 9 Immediate Severity: Critical
Status: Closed Last Modified: 2015-11-22 08:37:32
Resolution: Fixed Closed By: dkf
    Closed on: 2015-11-22 08:37:32
Description:
% oo::class create C {
method m {} {::oo::class destroy}
}
::C
% [C new] m

Program received signal SIGSEGV, Segmentation fault.
0x0000000000583404 in TclOORemoveFromInstances (oPtr=0x8e4be8, clsPtr=0x913528)
    at /home/dgp/fossil/tcl/generic/tclOO.c:1281
1281        FOREACH(instPtr, clsPtr->instances) {
Missing separate debuginfos, use: debuginfo-install glibc-2.17-78.el7.x86_64 zlib-1.2.7-13.el7.x86_64
(gdb) bt
#0  0x0000000000583404 in TclOORemoveFromInstances (oPtr=0x8e4be8, 
    clsPtr=0x913528) at /home/dgp/fossil/tcl/generic/tclOO.c:1281
#1  0x0000000000582bba in ObjectNamespaceDeleted (clientData=0x8e4be8)
    at /home/dgp/fossil/tcl/generic/tclOO.c:1135
#2  0x000000000052b59a in TclTeardownNamespace (nsPtr=0x8f5268)
    at /home/dgp/fossil/tcl/generic/tclNamesp.c:1220
#3  0x000000000052b270 in Tcl_DeleteNamespace (namespacePtr=0x8f5268)
    at /home/dgp/fossil/tcl/generic/tclNamesp.c:1028
#4  0x000000000052a61e in Tcl_PopCallFrame (interp=0x80a2f8)
    at /home/dgp/fossil/tcl/generic/tclNamesp.c:421
#5  0x0000000000546625 in InterpProcNR2 (data=0x91bdd0, interp=0x80a2f8, 
    result=0) at /home/dgp/fossil/tcl/generic/tclProc.c:1869
#6  0x0000000000414a54 in TclNRRunCallbacks (interp=0x80a2f8, result=0, 
    rootPtr=0x0) at /home/dgp/fossil/tcl/generic/tclBasic.c:4389
#7  0x00000000004172f8 in TclEvalObjEx (interp=0x80a2f8, 
    objPtr=0x6161616161616161, flags=131072, invoker=0x0, word=0)
    at /home/dgp/fossil/tcl/generic/tclBasic.c:5955
#8  0x0000000000417291 in Tcl_EvalObjEx (interp=0x80a2f8, 
    objPtr=0x6161616161616161, flags=131072)
    at /home/dgp/fossil/tcl/generic/tclBasic.c:5936
#9  0x00000000005b5084 in Tcl_RecordAndEvalObj (interp=0x80a2f8, 
    cmdPtr=0x8f4608, flags=131072)
    at /home/dgp/fossil/tcl/generic/tclHistory.c:190
#10 0x00000000005299e1 in Tcl_MainEx (argc=-1, argv=0x7fffffffd5f0, 
    appInitProc=0x40f386 <Tcl_AppInit>, interp=0x80a2f8)
    at /home/dgp/fossil/tcl/generic/tclMain.c:537
#11 0x000000000040f37f in main (argc=1, argv=0x7fffffffd5e8)
    at /home/dgp/fossil/tcl/unix/tclAppInit.c:84
(gdb) print *clsPtr
$1 = {thisPtr = 0x6161616161616161, refCount = 1633771873, flags = 1633771873, 
  superclasses = {num = 1633771873, list = 0x6161616161616161}, subclasses = {
    num = 1633771873, size = 1633771873, list = 0x6161616161616161}, 
  instances = {num = 1633771873, size = 1633771873, 
    list = 0x6161616161616161}, filters = {num = 1633771873, 
    list = 0x6161616161616161}, mixins = {num = 1633771873, 
    list = 0x6161616161616161}, mixinSubs = {num = 1633771873, 
    size = 1633771873, list = 0x6161616161616161}, classMethods = {
    buckets = 0x6161616161616161, staticBuckets = {0x6161616161616161, 
      0x6161616161616161, 0x6161616161616161, 0x6161616161616161}, 
    numBuckets = 1633771873, numEntries = 1633771873, 
    rebuildSize = 1633771873, downShift = 1633771873, mask = 1633771873, 
    keyType = 1633771873, findProc = 0x6161616161616161, 
    createProc = 0x6161616161616161, typePtr = 0x6161616161616161}, 
  constructorPtr = 0x6161616161616161, destructorPtr = 0x6161616161616161, 
  metadataPtr = 0x6161616161616161, constructorChainPtr = 0x6161616161616161, 
  destructorChainPtr = 0x6161616161616161, 
  classChainCache = 0x6161616161616161, variables = {num = 1633771873, 
    list = 0x6161616161616161}}

Trouble is that the clsPtr value has already been freed.
Somewhere the AddRef/DelRef is off.
User Comments: dkf added on 2015-11-22 08:37:32:

Backported.


dkf added on 2015-11-21 22:25:41:

Nasty. The simplest possible change doesn't work because it causes other tests to blow up. And in any case, mixins had the same problem too (though with more obscurity; fewer people use them). I'll keep this open as a reminder to me to fix it in the package version of TclOO, which will have the identical issue.