#4040 glob can cause crash on windows Tcl8.5.2

obsolete: 8.5.2
closed-fixed
9
2008-06-29
2008-06-20
Anonymous
No

This glob has crashed my windows on
with Tcl8.5.2

glob -nocomplain -directory {} anything

Artur
mail@xdobry.de

Discussion

  • Donal K. Fellows

    • labels: 105657 --> 36. Pathname Management
    • priority: 5 --> 9
    • assigned_to: dkf --> vincentdarley
     
  • Don Porter

    Don Porter - 2008-06-23

    Logged In: YES
    user_id=80530
    Originator: NO

    crashes on unix too.

     
  • Don Porter

    Don Porter - 2008-06-23

    Logged In: YES
    user_id=80530
    Originator: NO

    % glob -nocomplain -directory {} anything

    Program received signal SIGSEGV, Segmentation fault.
    0x0807c3db in Tcl_DbIncrRefCount (objPtr=0x0,
    file=0x8172768 "/home/dgp/cvs/tcl/unix/../generic/tclPathObj.c", line=1772)
    at /home/dgp/cvs/tcl/unix/../generic/tclObj.c:3088
    3088 if (objPtr->refCount == 0x61616161) {
    (gdb) bt
    #0 0x0807c3db in Tcl_DbIncrRefCount (objPtr=0x0,
    file=0x8172768 "/home/dgp/cvs/tcl/unix/../generic/tclPathObj.c", line=1772)
    at /home/dgp/cvs/tcl/unix/../generic/tclObj.c:3088
    #1 0x080827a8 in Tcl_FSGetNormalizedPath (interp=0x0, pathPtr=0x9d1e850)
    at /home/dgp/cvs/tcl/unix/../generic/tclPathObj.c:1772
    #2 0x080ae733 in TclNativeCreateNativeRep (pathPtr=0x9d1e850)
    at /home/dgp/cvs/tcl/unix/../unix/tclUnixFile.c:1104
    #3 0x08082d79 in Tcl_FSGetInternalRep (pathPtr=0x9d1e850, fsPtr=0x8188f40)
    at /home/dgp/cvs/tcl/unix/../generic/tclPathObj.c:2069
    #4 0x0806bb9b in Tcl_FSGetNativePath (pathPtr=0x9d1e850)
    at /home/dgp/cvs/tcl/unix/../generic/tclIOUtil.c:4290
    #5 0x080ad679 in TclpMatchInDirectory (interp=0x9cd18c8, resultPtr=0x9d13200,
    pathPtr=0x9d1e850, pattern=0x0, types=0x0)
    at /home/dgp/cvs/tcl/unix/../unix/tclUnixFile.c:235
    #6 0x08068974 in Tcl_FSMatchInDirectory (interp=0x9cd18c8,
    resultPtr=0x9d13200, pathPtr=0x9d1e850, pattern=0x0, types=0x0)
    at /home/dgp/cvs/tcl/unix/../generic/tclIOUtil.c:1056
    #7 0x081473d7 in DoGlob (interp=0x9cd18c8, matchesObj=0x9d13200,
    separators=0x8181bfe "/", pathPtr=0x9d06d18, flags=4,
    pattern=0x9d18080 "anything", types=0x0)
    at /home/dgp/cvs/tcl/unix/../generic/tclFileName.c:2457

     
  • Don Porter

    Don Porter - 2008-06-23

    Logged In: YES
    user_id=80530
    Originator: NO

    Add the command

    cd [pwd]

    before the [glob] and the crash
    doesn't happen.

    Suggests that at least one contibutor
    to the error is that Tcl's internal
    record of what is the current working
    directory is not initialized at a time
    when other parts of Tcl's filesystem
    code may be assuming that it is initialized.

     
  • Don Porter

    Don Porter - 2008-06-23

    Logged In: YES
    user_id=80530
    Originator: NO

    From the comments about 'struct FsPath'
    on lines 57-64 of tclPathObj.c:

    * (i) flags == 0, => Ordinary path.
    *
    * translatedPathPtr contains the translated path (which may be a circular
    * reference to the object itself). If it is NULL then the path is pure
    * normalized (and the normPathPtr will be a circular reference). cwdPtr is
    * null for an absolute path, and non-null for a relative path (unless the cwd
    * has never been set, in which case the cwdPtr may also be null for a
    * relative path).

    Take care to note that cwdPtr==NULL is possible for a
    relative path when the global cwd has never been set.
    The code at lines 1773-1174 (in Tcl_FSGetNormalizedPath())
    fails to account for this possibility.

     
  • Don Porter

    Don Porter - 2008-06-24
    • assigned_to: vincentdarley --> dgp
     
  • Don Porter

    Don Porter - 2008-06-24

    Logged In: YES
    user_id=80530
    Originator: NO

    Lines 1773-1774 are more reasonable than
    I thought. When they run, we have already
    called Tcl_FSGetNormalizedPath() on
    fsPathPtr->cwdPtr, so for any normal value,
    that call should have established
    cwdPtr!=NULL. That's only false because
    the empty string value as a pathname is
    so weird (see 2001389).

     
  • Don Porter

    Don Porter - 2008-06-24

    Logged In: YES
    user_id=80530
    Originator: NO

    here's a patch to stop the crash
    without redesigning the world

    File Added: 1999716.patch

     
  • Don Porter

    Don Porter - 2008-06-24
     
  • Don Porter

    Don Porter - 2008-06-24
    • status: open --> closed-fixed
     
  • Don Porter

    Don Porter - 2008-06-24

    Logged In: YES
    user_id=80530
    Originator: NO

    patch committed for 8.6a1 and 8.5.3.

    No backport to 8.4.* since the bug
    hasn't been demo'd there.

     
  • Rolf Ade

    Rolf Ade - 2008-06-29

    Logged In: YES
    user_id=13222
    Originator: NO

    The fix seems to leak.

    With 8.5.3rc0 w/ 2004654 patch the following script shows the leak:

    while 1 {
    interp create moo
    moo eval {
    package require tcltest
    namespace import tcltest::*

    proc createfile {file {string a}} {
    set f [open $file w]
    puts -nonewline $f $string
    close $f
    return $string
    }

    proc cleanup {args} {
    set wd [list .]
    foreach p [concat $wd $args] {
    set x ""
    catch {
    set x [glob -directory $p tf* td*]
    }
    foreach file $x {
    if {
    [catch {file delete -force -- $file}]
    && [testConstraint testchmod]
    } then {
    catch {openup $file}
    catch {file delete -force -- $file}
    }
    }
    }
    }

    for {set i 0} {$i < 1000} {incr i} {
    test fCmd-10.11 {file copy: copy to empty file name} -setup {
    cleanup
    } -returnCodes error -body {
    createfile tf1
    file copy tf1 ""
    } -result {error copying "tf1" to "": no such file or directory}
    }
    }
    puts moo
    interp delete moo
    }

    The script leaks slowly enough, to be watched with top without danger.

    The tests fCmd-10.11 and fCmd-10.12 out of the test suite trigger the leak. Attached is the relevant part of a valgrind output (-DPURIFY build).

     
  • Rolf Ade

    Rolf Ade - 2008-06-29

    Logged In: YES
    user_id=13222
    Originator: NO

    Can't attach (not my bug), here's the valgrind output:

    ==2077== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 105 from 3)
    ==2077== malloc/free: in use at exit: 218 bytes in 8 blocks.
    ==2077== malloc/free: 35,978 allocs, 35,970 frees, 2,582,181 bytes allocated.
    ==2077== For counts of detected errors, rerun with: -v
    ==2077== searching for pointers to 8 not-freed blocks.
    ==2077== checked 110,236 bytes.
    ==2077==
    ==2077== 218 (24 direct, 194 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
    ==2077== at 0x4019925: malloc (m_replacemalloc/vg_replace_malloc.c:207)
    ==2077== by 0x404038D: TclpAlloc (/home/rolf/tcltk/tcl8.5.3/generic/tclAlloc.c:706)
    ==2077== by 0x404A87D: Tcl_Alloc (/home/rolf/tcltk/tcl8.5.3/generic/tclCkalloc.c:1019)
    ==2077== by 0x40EB07C: Tcl_NewStringObj (/home/rolf/tcltk/tcl8.5.3/generic/tclStringObj.c:210)
    ==2077== by 0x40D9CE6: TclSubstTokens (/home/rolf/tcltk/tcl8.5.3/generic/tclParse.c:2252)
    ==2077== by 0x4044BDC: TclEvalEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4191)
    ==2077== by 0x404479F: Tcl_EvalEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4002)
    ==2077== by 0x40456F9: TclEvalObjEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4674)
    ==2077== by 0x404542A: Tcl_EvalObjEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4555)
    ==2077== by 0x40E428C: Tcl_UplevelObjCmd (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:911)
    ==2077== by 0x4044126: TclEvalObjvInternal (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3649)
    ==2077== by 0x4094C10: TclExecuteByteCode (/home/rolf/tcltk/tcl8.5.3/generic/tclExecute.c:2327)
    ==2077== by 0x40E5062: TclObjInterpProcCore (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:1721)
    ==2077== by 0x40E4FBC: TclObjInterpProc (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:1615)
    ==2077== by 0x4044126: TclEvalObjvInternal (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3649)
    ==2077== by 0x4044618: Tcl_EvalObjv (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3844)
    ==2077== by 0x4045641: TclEvalObjEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4643)
    ==2077== by 0x404542A: Tcl_EvalObjEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4555)
    ==2077== by 0x40E428C: Tcl_UplevelObjCmd (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:911)
    ==2077== by 0x4044126: TclEvalObjvInternal (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3649)
    ==2077== by 0x4094C10: TclExecuteByteCode (/home/rolf/tcltk/tcl8.5.3/generic/tclExecute.c:2327)
    ==2077== by 0x40E5062: TclObjInterpProcCore (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:1721)
    ==2077== by 0x40E4FBC: TclObjInterpProc (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:1615)
    ==2077== by 0x4044126: TclEvalObjvInternal (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3649)
    ==2077== by 0x4044618: Tcl_EvalObjv (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3844)
    ==2077== by 0x4045641: TclEvalObjEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4643)
    ==2077== by 0x404542A: Tcl_EvalObjEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4555)
    ==2077== by 0x40E428C: Tcl_UplevelObjCmd (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:911)
    ==2077== by 0x4044126: TclEvalObjvInternal (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3649)
    ==2077== by 0x4094C10: TclExecuteByteCode (/home/rolf/tcltk/tcl8.5.3/generic/tclExecute.c:2327)
    ==2077== by 0x40E5062: TclObjInterpProcCore (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:1721)
    ==2077== by 0x40E4FBC: TclObjInterpProc (/home/rolf/tcltk/tcl8.5.3/generic/tclProc.c:1615)
    ==2077== by 0x40CC576: InvokeImportedCmd (/home/rolf/tcltk/tcl8.5.3/generic/tclNamesp.c:1889)
    ==2077== by 0x4044126: TclEvalObjvInternal (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3649)
    ==2077== by 0x4094C10: TclExecuteByteCode (/home/rolf/tcltk/tcl8.5.3/generic/tclExecute.c:2327)
    ==2077== by 0x40931A3: TclCompEvalObj (/home/rolf/tcltk/tcl8.5.3/generic/tclExecute.c:1473)
    ==2077== by 0x404589D: TclEvalObjEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4763)
    ==2077== by 0x40AD119: SlaveEval (/home/rolf/tcltk/tcl8.5.3/generic/tclInterp.c:2479)
    ==2077== by 0x40ACC31: SlaveObjCmd (/home/rolf/tcltk/tcl8.5.3/generic/tclInterp.c:2288)
    ==2077== by 0x4044126: TclEvalObjvInternal (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:3649)
    ==2077== by 0x4045021: TclEvalEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4296)
    ==2077== by 0x404479F: Tcl_EvalEx (/home/rolf/tcltk/tcl8.5.3/generic/tclBasic.c:4002)
    ==2077== by 0x40C1D43: Tcl_FSEvalFileEx (/home/rolf/tcltk/tcl8.5.3/generic/tclIOUtil.c:1820)
    ==2077== by 0x40C9CD7: Tcl_Main (/home/rolf/tcltk/tcl8.5.3/generic/tclMain.c:441)
    ==2077== by 0x804C975: main (/home/rolf/tcltk/tcl8.5.3/unix/tclAppInit.c:87)
    ==2077==
    ==2077== LEAK SUMMARY:
    ==2077== definitely lost: 24 bytes in 1 blocks.
    ==2077== indirectly lost: 194 bytes in 7 blocks.
    ==2077== possibly lost: 0 bytes in 0 blocks.
    ==2077== still reachable: 0 bytes in 0 blocks.
    ==2077== suppressed: 0 bytes in 0 blocks.

     
  • Don Porter

    Don Porter - 2008-06-29
    • status: closed-fixed --> open-fixed
     
  • Don Porter

    Don Porter - 2008-06-29

    Logged In: YES
    user_id=80530
    Originator: NO

    pointsman reports that commenting
    out line 1910 of Revision 1.66.2.3
    of tclPathObj.c plugs the leak.

    This indicates that somehow refCounting
    is broken, but I'm not yet able to
    sort it out. I think it has something
    to do with not accounting for the strange
    Tcl_FSGetCwd() interface that increments
    refcount for the caller.

     
  • Don Porter

    Don Porter - 2008-06-29

    Logged In: YES
    user_id=80530
    Originator: NO

    The trouble is the if () {} else {}
    on lines 1970 - 1994. With the recent
    changes, the empty string path actually
    needs to take both branches, so the logic
    needs a revision.

     
  • Don Porter

    Don Porter - 2008-06-29

    Logged In: YES
    user_id=80530
    Originator: NO

    leak plugged for 8.5.3 and 8.6a2.

     
  • Don Porter

    Don Porter - 2008-06-29
    • status: open-fixed --> closed-fixed