Tcl Source Code

View Ticket
Login
Ticket UUID: 2688063
Title: segfault in test error-9.5 (try)
Type: Bug Version: obsolete: 8.6b1.1
Submitter: mistachkin Created on: 2009-03-15 23:48:48
Subsystem: 18. Commands M-Z Assigned To: dkf
Priority: 9 Immediate Severity:
Status: Closed Last Modified: 2009-03-16 19:23:54
Resolution: Fixed Closed By: dkf
    Closed on: 2009-03-16 10:22:38
Description:
OS is FreeBSD on x86.  Threaded debug build.

Here is the stack trace:

Core was generated by `tcltest'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from ./tcl/tcl8.6/tcl/unix/libtcl8.6.so...done.
Reading symbols from /usr/lib/libm.so.2...done.
Reading symbols from /usr/lib/libc_r.so.4...done.
Reading symbols from /usr/libexec/ld-elf.so.1...done.
#0  0x480b6a02 in TclNREvalObjEx (interp=0x8094020, objPtr=0x61616161, flags=0, invoker=0x8096888, word=-1)
    at ./tcl/tcl8.6/tcl/generic/tclBasic.c:5738
5738        List *listRepPtr = objPtr->internalRep.twoPtrValue.ptr1;
(gdb) bt
#0  0x480b6a02 in TclNREvalObjEx (interp=0x8094020, objPtr=0x61616161, flags=0, invoker=0x8096888, word=-1)
    at ./tcl/tcl8.6/tcl/generic/tclBasic.c:5738
#1  0x480d82b1 in TryPostBody (data=0x828f5a4, interp=0x8094020, result=1) at ./tcl/tcl8.6/tcl/generic/tclCmdMZ.c:4391
#2  0x480b46e9 in TclNRRunCallbacks (interp=0x8094020, result=0, rootPtr=0x828f020, tebcCall=1) at ./tcl/tcl8.6/tcl/generic/tclBasic.c:4244
#3  0x48132060 in TclExecuteByteCode (interp=0x8094020, codePtr=0x828ad20) at ./tcl/tcl8.6/tcl/generic/tclExecute.c:7844
#4  0x480b4a21 in NRCallTEBC (data=0x8171024, interp=0x8094020, result=0) at ./tcl/tcl8.6/tcl/generic/tclBasic.c:4329
#5  0x480b46e9 in TclNRRunCallbacks (interp=0x8094020, result=0, rootPtr=0x0, tebcCall=0) at ./tcl/tcl8.6/tcl/generic/tclBasic.c:4244
#6  0x480b4173 in Tcl_EvalObjv (interp=0x8094020, objc=4, objv=0x80961e8, flags=2097152) at ./tcl/tcl8.6/tcl/generic/tclBasic.c:4027
#7  0x480b5f93 in TclEvalEx (interp=0x8094020,
    script=0x8110020 "# Commands covered:  error, catch, throw, try\n#\n# This file contains a collection of tests for one or more of the Tcl built-in\n# commands. Sourcing this file into Tcl runs the tests and generates outp"..., numBytes=26388, flags=0, line=21)
    at ./tcl/tcl8.6/tcl/generic/tclBasic.c:5122
#8  0x480b5641 in Tcl_EvalEx (interp=0x8094020,
    script=0x8110020 "# Commands covered:  error, catch, throw, try\n#\n# This file contains a collection of tests for one or more of the Tcl built-in\n# commands. Sourcing this file into Tcl runs the tests and generates outp"..., numBytes=26388, flags=0)
    at ./tcl/tcl8.6/tcl/generic/tclBasic.c:4823
#9  0x4815ce7f in Tcl_FSEvalFileEx (interp=0x8094020, pathPtr=0x80dac20, encodingName=0x0) at ./tcl/tcl8.6/tcl/generic/tclIOUtil.c:1753
#10 0x48166bf2 in Tcl_Main (argc=-1, argv=0xbfbff8bc, appInitProc=0x804cce4 <Tcl_AppInit>) at ./tcl/tcl8.6/tcl/generic/tclMain.c:353
#11 0x804ccd4 in main (argc=36, argv=0xbfbff82c) at ./tcl/tcl8.6/tcl/unix/tclAppInit.c:87
User Comments: ferrieux added on 2009-03-16 19:23:54:
Hmm so it looks like you accepted my patch (and renamed a few things for readability).
Any thing else ? Thanks for the detailed comment BTW.

dkf added on 2009-03-16 17:22:38:

allow_comments - 1

Oops. I wonder why this never showed up in my testing. Oh well.

ferrieux added on 2009-03-16 16:04:54:
Thanks Joe for this detailed output, it makes the bug obvious !
What happens is the following:
(1) handlersObj contains a list of sublists, tried each in turn (handlers[i]).
(2) when the matching one is found, its elements pointer is extracted into "info".
(3) that info contains the handlerObj as info[0], whose refcount is incr'ed
(4) then we decr the refcount of the handlersObj list, and handlerObj survives, but not the intermediary level handlers[i]
(5) then info[] is stale at the point where we use info[4]

The attached trivial patch just copies info[4] in a local until its use.
From my tests it seems that the associated Tcl_Obj has a refcount high enough so that it survives the decrrefcount of the whole tree, but I'm not sure.
A better solution would be to IncrRefCount(handlers[i]), but I daren't do that because I don't know the best point to DecrRefCount it afterwards.

Please Donal and Joe, review ;-)

ferrieux added on 2009-03-16 15:45:01:

File Added - 318003: try.patch

File Added: try.patch

mistachkin added on 2009-03-16 08:36:17:
   1. ==3091== Invalid read of size 4
   2. ==3091== at 0x4077F1F: TryPostBody (tclCmdMZ.c:4391)
   3. ==3091== by 0x40539B7: TclNRRunCallbacks (tclBasic.c:4244)
   4. ==3091== by 0x40D3F3C: TclExecuteByteCode (tclExecute.c:7844)
   5. ==3091== by 0x4053CFE: NRCallTEBC (tclBasic.c:4329)
   6. ==3091== by 0x40539B7: TclNRRunCallbacks (tclBasic.c:4244)
   7. ==3091== by 0x405359D: Tcl_EvalObjv (tclBasic.c:4027)
   8. ==3091== by 0x40552FB: TclEvalEx (tclBasic.c:5122)
   9. ==3091== by 0x4054978: Tcl_EvalEx (tclBasic.c:4823)
  10. ==3091== by 0x41000A4: Tcl_FSEvalFileEx (tclIOUtil.c:1753)
  11. ==3091== by 0x410A065: Tcl_Main (tclMain.c:353)
  12. ==3091== by 0x804D0EB: main (tclAppInit.c:87)
  13. ==3091== Address 0x5f1f868 is 64 bytes inside a block of size 80 free'd
  14. ==3091== at 0x402265C: free (vg_replace_malloc.c:323)
  15. ==3091== by 0x404E66F: TclpFree (tclAlloc.c:729)
  16. ==3091== by 0x405F5EC: Tcl_DbCkfree (tclCkalloc.c:633)
  17. ==3091== by 0x4105B78: FreeListInternalRep (tclListObj.c:1612)
  18. ==3091== by 0x411762B: TclFreeObj (tclObj.c:883)
  19. ==3091== by 0x411A2DB: Tcl_DbDecrRefCount (tclObj.c:3218)
  20. ==3091== by 0x4077EDE: TryPostBody (tclCmdMZ.c:4388)
  21. ==3091== by 0x40539B7: TclNRRunCallbacks (tclBasic.c:4244)
  22. ==3091== by 0x40D3F3C: TclExecuteByteCode (tclExecute.c:7844)
  23. ==3091== by 0x4053CFE: NRCallTEBC (tclBasic.c:4329)
  24. ==3091== by 0x40539B7: TclNRRunCallbacks (tclBasic.c:4244)
  25. ==3091== by 0x405359D: Tcl_EvalObjv (tclBasic.c:4027)

Attachments: