#3941 segfault in oo.test on object destroy for x86_64 arch

obsolete: 8.5.1
closed-fixed
8
2014-08-24
2008-03-02
No

Executing oo.test on x86_64 results in segmentation fault for test case oo-14.3. See backtrace:

% valgrind --db-attach=yes tclsh oo.test
==6797== Memcheck, a memory error detector.
==6797== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==6797== Using LibVEX rev 1804, a library for dynamic binary translation.
==6797== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==6797== Using valgrind-3.3.0, a dynamic binary instrumentation framework.
==6797== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==6797== For more details, rerun with: -v
==6797==
==6797== Invalid read of size 4
==6797== at 0x5D64A29: ReleaseClassContents (tclOO.c:599)
==6797== by 0x5D64930: ObjectRenamedTrace (tclOO.c:555)
==6797== by 0x4E5F737: CallCommandTraces (tclBasic.c:2918)
==6797== by 0x4E5F3CC: Tcl_DeleteCommandFromToken (tclBasic.c:2741)
==6797== by 0x5D68462: ObjectDestroy (tclOO.c:2140)
==6797== by 0x5D71FA8: BasicClassMethodInvoke (tclOOMethod.c:315)
==6797== by 0x5D6A95C: TclOOInvokeContext (tclOOCall.c:218)
==6797== by 0x5D67D18: TclOOObjectCmdCore (tclOO.c:1895)
==6797== by 0x5D678D2: PublicObjectCmd (tclOO.c:1756)
==6797== by 0x4E60813: TclEvalObjvInternal (tclBasic.c:3647)
==6797== by 0x4E61B08: TclEvalEx (tclBasic.c:4294)
==6797== by 0x4E6106D: Tcl_EvalEx (tclBasic.c:4000)
==6797== Address 0x6c346e8 is 8 bytes inside a block of size 248 free'd
==6797== at 0x4C22B9E: free (in /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==6797== by 0x4E5C36D: TclpFree (tclAlloc.c:729)
==6797== by 0x4E68084: Tcl_Free (tclCkalloc.c:1182)
==6797== by 0x4F195AC: Tcl_Release (tclPreserve.c:230)
==6797== by 0x5D64968: ObjectRenamedTrace (tclOO.c:559)
==6797== by 0x4E5F737: CallCommandTraces (tclBasic.c:2918)
==6797== by 0x4E5F3CC: Tcl_DeleteCommandFromToken (tclBasic.c:2741)
==6797== by 0x5D68462: ObjectDestroy (tclOO.c:2140)
==6797== by 0x5D71FA8: BasicClassMethodInvoke (tclOOMethod.c:315)
==6797== by 0x5D6A95C: TclOOInvokeContext (tclOOCall.c:218)
==6797== by 0x5D67D18: TclOOObjectCmdCore (tclOO.c:1895)
==6797== by 0x5D678D2: PublicObjectCmd (tclOO.c:1756)
==6797==
==6797== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y
==6797== starting debugger with cmd: /usr/bin/gdb -nw /proc/6798/fd/1014 6798
GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
Attaching to program: /proc/6798/fd/1014, process 6798
Reading symbols from /usr/lib64/valgrind/amd64-linux/vgpreload_core.so...done.
Loaded symbols for /usr/lib64/valgrind/amd64-linux/vgpreload_core.so
Reading symbols from /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so...done.
Loaded symbols for /usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so
Reading symbols from /usr/local/tcl/8.5.1-dbg/lib/libtcl8.5.so...done.
Loaded symbols for /usr/local/tcl/8.5.1-dbg/lib/libtcl8.5.so
Reading symbols from /lib64/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib64/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib64/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /usr/local/tcl/8.5.1-dbg/lib/TclOO0.2a0/libTclOO0.2a0.so...done.
Loaded symbols for /usr/local/tcl/8.5.1-dbg/lib/TclOO0.2a0/libTclOO0.2a0.so
0x0000000005d64a29 in ReleaseClassContents (interp=0x5963d30, oPtr=0x6c2ff18) at ./generic/tclOO.c:599
599 if (!(list[i]->flags & OBJECT_DELETED) && interp != NULL) {
(gdb) p i
$1 = 0
(gdb) bt
#0 0x0000000005d64a29 in ReleaseClassContents (interp=0x5963d30, oPtr=0x6c2ff18) at ./generic/tclOO.c:599
#1 0x0000000005d64931 in ObjectRenamedTrace (clientData=0x6c2ff18, interp=0x5963d30, oldName=0x6c3d030 "::mix", newName=0x0,
flags=16512) at ./generic/tclOO.c:555
#2 0x0000000004e5f738 in CallCommandTraces (iPtr=0x5963d30, cmdPtr=0x6c30420, oldName=0x6c3d030 "::mix", newName=0x0, flags=16512)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:2918
#3 0x0000000004e5f3cd in Tcl_DeleteCommandFromToken (interp=0x5963d30, cmd=0x6c30420)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:2741
#4 0x0000000005d68463 in ObjectDestroy (clientData=0x0, interp=0x5963d30, context=0x6c3ce30, objc=2, objv=0x5965ab0)
at ./generic/tclOO.c:2140
#5 0x0000000005d71fa9 in BasicClassMethodInvoke (clientData=0x5f76940, interp=0x5963d30, context=0x6c3ce30, objc=2,
objv=0x5965ab0) at ./generic/tclOOMethod.c:315
#6 0x0000000005d6a95d in TclOOInvokeContext (interp=0x5963d30, contextPtr=0x6c3ce30, objc=2, objv=0x5965ab0)
at ./generic/tclOOCall.c:218
#7 0x0000000005d67d19 in TclOOObjectCmdCore (oPtr=0x6c2ff18, interp=0x5963d30, objc=2, objv=0x5965ab0, flags=1,
cachePtr=0x6c2ffd8, startCls=0x0) at ./generic/tclOO.c:1895
#8 0x0000000005d678d3 in PublicObjectCmd (clientData=0x6c2ff18, interp=0x5963d30, objc=2, objv=0x5965ab0)
at ./generic/tclOO.c:1756
#9 0x0000000004e60814 in TclEvalObjvInternal (interp=0x5963d30, objc=2, objv=0x5965ab0, command=0x6c2aa4b "mix destroy\n",
length=12, flags=0) at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:3647
#10 0x0000000004e61b09 in TclEvalEx (interp=0x5963d30, script=0x6c2aa38 "\n c destroy\n mix destroy\n", numBytes=31,
flags=262144, line=3) at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:4294
#11 0x0000000004e6106e in Tcl_EvalEx (interp=0x5963d30, script=0x6c2aa38 "\n c destroy\n mix destroy\n", numBytes=31,
flags=262144) at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:4000
#12 0x0000000004e62378 in TclEvalObjEx (interp=0x5963d30, objPtr=0x6c2a9d8, flags=262144, invoker=0x0, word=0)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:4672
#13 0x0000000004e61fd8 in Tcl_EvalObjEx (interp=0x5963d30, objPtr=0x6c2ff18, flags=262144)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:4553
#14 0x0000000004f1acca in Tcl_UplevelObjCmd (dummy=0x0, interp=0x5963d30, objc=1, objv=0x59657f0)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclProc.c:911
#15 0x0000000004e60814 in TclEvalObjvInternal (interp=0x5963d30, objc=3, objv=0x59657e0,
command=0xffffffffffffffff <Address 0xffffffffffffffff out of bounds>, length=-1, flags=0)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:3647
#16 0x0000000004ec2e66 in TclExecuteByteCode (interp=0x5963d30, codePtr=0x600c6b8)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclExecute.c:2255
#17 0x0000000004f1bd27 in TclObjInterpProcCore (interp=0x5963d30, procNameObj=0x6c2a418, skip=1,
errorProc=0x4f1c431 <MakeProcError>) at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclProc.c:1721
#18 0x0000000004f1bc23 in TclObjInterpProc (clientData=0x5d17298, interp=0x5963d30, objc=11, objv=0x5965100)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclProc.c:1615
#19 0x0000000004efed32 in InvokeImportedCmd (clientData=0x5f85b80, interp=0x5963d30, objc=11, objv=0x5965100)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclNamesp.c:1889
#20 0x0000000004e60814 in TclEvalObjvInternal (interp=0x5963d30, objc=11, objv=0x5965100,
command=0x59fbfea "test oo-14.3 {OO and mixins and filters - advanced case} -setup {\n oo::class create mix\n oo::class create c {\n\tmixin mix\n }\n c create i\n} -body {\n oo::define mix {\n\tmethod foo {} {retur"..., length=353, flags=0)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:3647
#21 0x0000000004e61b09 in TclEvalEx (interp=0x5963d30,
script=0x59f6b50 "# This file contains a collection of tests for Tcl's built-in object system.\n# Sourcing this file into Tcl runs the tests and generates output for errors.\n# No output means no errors were found.\n#\n# C"..., numBytes=39130, flags=0,
line=737) at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:4294
#22 0x0000000004e6106e in Tcl_EvalEx (interp=0x5963d30,
script=0x59f6b50 "# This file contains a collection of tests for Tcl's built-in object system.\n# Sourcing this file into Tcl runs the tests and generates output for errors.\n# No output means no errors were found.\n#\n# C"..., numBytes=39130, flags=0)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclBasic.c:4000
#23 0x0000000004ef38dd in Tcl_FSEvalFileEx (interp=0x5963d30, pathPtr=0x599bcb0, encodingName=0x0)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclIOUtil.c:1825
#24 0x0000000004efc057 in Tcl_Main (argc=-1, argv=0x7fefffc78, appInitProc=0x4008f1 <Tcl_AppInit>)
at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../generic/tclMain.c:441
#25 0x00000000004008ea in main (argc=2, argv=0x7fefffc68) at /usr/local/tcl/8.5.1-dbg/src/tcl/unix/../unix/tclAppInit.c:87
(gdb)

Discussion

  • Donal K. Fellows

    Logged In: YES
    user_id=79902
    Originator: NO

    I can reproduce this with 32-bit Linux as long as both Tcl and TclOO have symbols turned on. (Thanks to Miguel for testing this config for me.)

     
  • Donal K. Fellows

    • priority: 5 --> 9
     
  • Anonymous - 2008-03-08

    Test script with random object create and destroy

     
  • Anonymous - 2008-03-08

    Logged In: YES
    user_id=1923679
    Originator: YES

    File Added: oodestroy

     
  • Anonymous - 2008-03-08

    valgrind report for 32-bit/debug

     
  • Anonymous - 2008-03-08

    Logged In: YES
    user_id=1923679
    Originator: YES

    File Added: valgrind-x86_32-dbg.log

     
  • Anonymous - 2008-03-08

    valgrind report for 32-bit/opt

     
  • Anonymous - 2008-03-08

    Logged In: YES
    user_id=1923679
    Originator: YES

    File Added: valgrind-x86_32-opt.log

     
  • Anonymous - 2008-03-08

    valgrind report for 64-bit/debug

     
  • Anonymous - 2008-03-08

    Logged In: YES
    user_id=1923679
    Originator: YES

    File Added: valgrind-x86_64-dbg.log

     
  • Anonymous - 2008-03-08

    Logged In: YES
    user_id=1923679
    Originator: YES

    File Added: valgrind-x86_64-opt.log

     
  • Anonymous - 2008-03-08

    valgrind report for 64-bit/opt

     
  • Anonymous - 2008-03-08

    Logged In: YES
    user_id=1923679
    Originator: YES

    There is another test script "oodestroy"
    attached, which shows quite consistent behavior
    independent of 32/64 bit arch and
    debug/optimized build. The script does NOT raise a
    segfault, but valgrind still reports illegal
    reads and memory leaks.

    Environment for x86_32:
    Gentoo 2007.0, gcc-4.1.2, glibc-2.6.1
    CFLAGS_DEBUG="-g -DPURIFY"
    CFLAGS_OPTIMIZE="-O2 -march=athlon-xp -mfpmath=sse -fomit-frame-pointer"

    Environment for x86_64:
    Gentoo 2007.0, gcc-4.1.2, glibc-2.6.1
    CFLAGS_DEBUG="-g -DPURIFY"
    CFLAGS_OPTIMIZE="-O2 -march=athlon64 -mfpmath=sse -fomit-frame-pointer"

    Tcl and TclOO configuration:
    debug: ./configure --enable-shared --enable-symbols --disable-threads --disable-xft --srcdir=/usr/local/tcl/8.5.1-dbg/src/tcl/unix --prefix=/usr/local/tcl/8.5.1-dbg
    opt: ./configure --enable-shared --disable-symbols --disable-threads --disable-xft --srcdir=/usr/local/tcl/8.5.1/src/tcl/unix --prefix=/usr/local/tcl/8.5.1

    See attached valgrind reports for all four
    cases. Hope this helps.

     
  • Donal K. Fellows

    • priority: 9 --> 8
     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902
    Originator: NO

    Can't reproduce with HEAD of TclOO run against HEAD of Tcl (full debug build of both, on 32-bit x86 Linux with gcc toolchain). No idea what's changed...

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902
    Originator: NO

    BTW, if you want to run the supposedly crashing test, use:
    make test TESTFLAGS="-constraints knownBug"

     
  • Anonymous - 2008-05-02

    valgrind report for 32-bit/debug on HEAD versions

     
  • Anonymous - 2008-05-02

    Logged In: YES
    user_id=1923679
    Originator: YES

    Tried again with HEAD version on 32-bit and 64-bit. It still fails at the same spot:

    ==16127== Invalid read of size 4
    ==16127== at 0x46E37A8: ReleaseClassContents (tclOO.c:602)

    0x046e37a8 in ReleaseClassContents (interp=0x42e3140, oPtr=0x5151358) at ./generic/tclOO.c:602
    602 if (!(list[i]->flags & OBJECT_DELETED) && interp != NULL) {
    (gdb) p list
    $1 = (Class **) 0x5153b00
    (gdb) p i
    $2 = 0
    (gdb) p list[i]
    $3 = (Class *) 0x5153300
    (gdb) p *list[i]
    $4 = {thisPtr = 0x5152a08, flags = 1, superclasses = {num = 0, list = 0x5153418}, subclasses = {num = 0, size = 0, list = 0x0},
    instances = {num = 0, size = 0, list = 0x0}, filters = {num = 0, list = 0x0}, mixins = {num = 0, list = 0x5153ac8}, mixinSubs = {
    num = 0, size = 0, list = 0x0}, classHierarchy = {num = 0, list = 0x51571e8}, classHierarchyEpoch = 78, classMethods = {
    buckets = 0x5153354, staticBuckets = {0x0, 0x0, 0x0, 0x0}, numBuckets = 4, numEntries = 0, rebuildSize = 12, downShift = 28,
    mask = 3, keyType = -1, findProc = 0x40bea2f <BogusFind>, createProc = 0x40bea64 <BogusCreate>, typePtr = 0x4149ca0},
    constructorPtr = 0x0, destructorPtr = 0x0, metadataPtr = 0x0}

    File Added: valgrind-8.6a0-20080502-x86_32-dbg.log

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902
    Originator: NO

    Finally managed to reproduce this on one of my development machines under an environment where I could see what was going wrong. Turned out to be a simple matter of needing to change how classes are unstitched from mixin classes. Fixed.

     
  • Donal K. Fellows

    • status: open --> closed-fixed