Share

Tk Toolkit

Tracker: Bugs

8 Threads: "called Tcl_Close on channel with refCount > 0" - ID: 1468291
Last Update: Attachment added ( hobbs )

When using vfs::mk4 and [file copy] and multi threading
on Windows, wish crashes with the error message:

"called Tcl_Close on channel with refCount > 0"

This issue applies only to the wish application or
tclkit on windows. Tclsh and tclkitsh on windows are
not affected. When using [file copy] on normal non-vfs
directories, everything is fine as well. Only with
*non-existing* vfs directories mounted via
vfs::mk4::Mount (or maybe other vfs::*::Mount's) the
crash appeared to me.

I've written a short script which makes it easy to
reproduce the bug:

# channel refcount bug
package require Thread
catch {console show}

set T [thread::create -preserved]

thread::send $T [list set D [file dirname [info script]]]

set script {
package require vfs::mk4

set logOpen 0
proc ::Log {msg} {
if {$::logOpen} {
set mode a
} else {
set mode w
set ::logOpen 1
}

set L [open [file join $::D log.txt] $mode]
puts $L $msg
close $L
}

Log $D
set src [file join $D test.txt]
set tdir [file join $D tdir.kit]
set dest [file join $tdir test.txt]
Log $dest

Log 1
set vfsh [vfs::mk4::Mount $tdir $tdir]
Log 2
file copy $src $dest
Log 3
vfs::mk4::Unmount $vfsh $tdir
Log 4
}

thread::send -async $T $script

# end channel bug script

When the directory exists, the crash does not happen,
but the script runs only until "Log 2".
It is not very clear to me whether this is a bug in Tk
(because it only appears with wish/windows) or vfs or
metakit.


Nobody/Anonymous ( nobody ) - 2006-04-11 09:03

8

Closed

Fixed

Jeffrey Hobbs

75. wish

obsolete: 8.4.13

Public


Comments ( 17 )

Date: 2006-05-26 19:44
Sender: hobbsSourceForge.net SubscriberProject Admin

Logged In: YES
user_id=72656

Applied to VFS.


Date: 2006-05-23 20:53
Sender: vincentdarley

Logged In: YES
user_id=32170

The workaround patch looks just fine to me (and indeed it
does seem like a weird thing to have to do to deal with
Tcl's behaviour).

Vince.



Date: 2006-05-10 05:54
Sender: hobbsSourceForge.net SubscriberProject Admin

Logged In: YES
user_id=72656

OK, I believe that I have found a work-around in vfs. While
you might be tempted to call this a vfs bug, it really is
more of having to deal with sneaky (stupid) std channel
auto-inheritance issues by the Tcl core.

The problem is that vfs uses Tcl_DetachChannel - but this is
specifically proscribed for std channels (which we only get
due to wacky core semantics). Attached is a patch against
vfs that checks if we are dealing with a std channel and
reverses the auto-inheritance magic by setting the std
channel in question to NULL and unregistering it with NULL
interp to just decr the refcount, then doing the detach.

Passing to Vince to vet and approve. It does correct the
reported bug. I suspect it may correct some other wackiness
we've seen with vfs-related early open file issues.

Again, I consider this a core misfeature, but this is a
valid work-around.


Date: 2006-05-10 05:06
Sender: hobbsSourceForge.net SubscriberProject Admin

Logged In: YES
user_id=72656

I have confirmed that it is the std channel inheritance
magic that is the problem. This would best be removed for
8.5, but that would require the ability to enforce a new
channel as a std channel from Tcl.

BTW, the issue with only running to "Log 2" is that you
don't use [file copy -force $src $dest], so it will fail at
that point if you've successfully run once. I've attached a
more elaborate test script.


Date: 2006-05-10 03:50
Sender: hobbsSourceForge.net SubscriberProject Admin

Logged In: YES
user_id=72656

OK, I have found that it is likely an issue with Tcl's
channel inheritance into std channels. A work-around would
be to add:

set fake_stdin [open NUL: r]
set fake_stdout [open NUL: w]
set fake_stderr [open NUL: w]

at the start of the script you pass to the thread.


Date: 2006-05-10 00:24
Sender: hobbsSourceForge.net SubscriberProject Admin

Logged In: YES
user_id=72656

A stack trace, fwiw:

Tcl_Panic(const char * 0x100b342c) line 134 + 13 bytes
Tcl_Close(Tcl_Interp * 0x00d27318, Tcl_Channel_ *
0x011f8e30) line 2582 + 10 bytes
TclCrossFilesystemCopy(Tcl_Interp * 0x00d27318, Tcl_Obj *
0x011c1038, Tcl_Obj * 0x00d30300) line 3683 + 13 bytes
CopyRenameOneFile(Tcl_Interp * 0x00d27318, Tcl_Obj *
0x011c1038, Tcl_Obj * 0x00d30300, int 0x00000001, int
0x00000000) line 678 + 17 bytes
FileCopyRename(Tcl_Interp * 0x00d27318, int 0x00000004,
Tcl_Obj * const * 0x00d340a0, int 0x00000001) line 166 + 38
bytes
TclFileCopyCmd(Tcl_Interp * 0x00d27318, int 0x00000004,
Tcl_Obj * const * 0x00d340a0) line 85 + 19 bytes
Tcl_FileObjCmd(void * 0x00000000, Tcl_Interp * 0x00d27318,
int 0x00000004, Tcl_Obj * const * 0x00d340a0) line 868 + 17
bytes
TclEvalObjvInternal(Tcl_Interp * 0x00d27318, int 0x00000004,
Tcl_Obj * const * 0x00d340a0, const char * 0x00000000, int
0x00000000, int 0x00000000) line 3087 + 25 bytes
TclExecuteByteCode(Tcl_Interp * 0x00d27318, ByteCode *
0x00d29f18) line 1419 + 33 bytes
TclCompEvalObj(Tcl_Interp * 0x00d27318, Tcl_Obj *
0x00d30108) line 981 + 13 bytes
Tcl_EvalObjEx(Tcl_Interp * 0x00d27318, Tcl_Obj * 0x00d30108,
int 0x00000000) line 4051 + 13 bytes
Tcl_CatchObjCmd(void * 0x00000000, Tcl_Interp * 0x00d27318,
int 0x00000003, Tcl_Obj * const * 0x00d34094) line 248 + 18
bytes
TclEvalObjvInternal(Tcl_Interp * 0x00d27318, int 0x00000003,
Tcl_Obj * const * 0x00d34094, const char * 0x00000000, int
0x00000000, int 0x00000000) line 3087 + 25 bytes
TclExecuteByteCode(Tcl_Interp * 0x00d27318, ByteCode *
0x00c768e0) line 1419 + 33 bytes
Tcl_ExprObj(Tcl_Interp * 0x00d27318, Tcl_Obj * 0x00d30210,
Tcl_Obj * * 0x00f6f978) line 832 + 13 bytes
Tcl_ExprBooleanObj(Tcl_Interp * 0x00d27318, Tcl_Obj *
0x00d30210, int * 0x00f6f9a0) line 4431 + 17 bytes
Tcl_IfObjCmd(void * 0x00000000, Tcl_Interp * 0x00d27318, int
0x00000003, Tcl_Obj * const * 0x00f6fbbc) line 210 + 23 bytes
TclEvalObjvInternal(Tcl_Interp * 0x00d27318, int 0x00000003,
Tcl_Obj * const * 0x00f6fbbc, const char * 0x00cf85bd, int
0x0000031d, int 0x00000000) line 3087 + 25 bytes
Tcl_EvalEx(Tcl_Interp * 0x00d27318, const char * 0x00cf85b8,
int 0x00000322, int 0x00020000) line 3690 + 36 bytes
THREAD263! 00e52500()



Date: 2006-05-10 00:19
Sender: hobbsSourceForge.net SubscriberProject Admin

Logged In: YES
user_id=72656

OK - figured out some issues.

If test.txt doesn't exist, then you just hang on the 'file
copy' ... oddly, it isn't just giving an error. When I
finally created that file, I was able to see the error.


Date: 2006-05-09 23:57
Sender: hobbsSourceForge.net SubscriberProject Admin

Logged In: YES
user_id=72656

When building Tcl/Tk 8.5 from CVS head and using the Thread
and vfs modules from ActiveTcl 8.4.13 (threaded) on Windows,
I am not able to reproduce any crashes.

Note that when I originally tried against 8.4.13 with a
slightly older pre-build, I did crash with a Tcl_HashTable
entry panic. I did resolve that issue in the Thread code
already, but it is post-2.6.3, just in CVS.

Can you please confirm the exact ChangeLog level of your
build chain?


Date: 2006-05-09 16:02
Sender: ctasada

Logged In: YES
user_id=340696

I think that I don't need the TCLLIBPATH since the auto_path
variable is correctly set. Anyway I did and I got the same
result.

If I do a "package require vfs" in the script it works
correctly, but if I do the same inside the thread it cannot
be found.

And the strangest part is when I do the same with wish and
it can find the vfs, but then crashes with the "called
Tcl_Close on channel with refCount > 0"

Can you reproduce this behaviour in your system?


Date: 2006-05-09 15:46
Sender: dgpProject Admin

Logged In: YES
user_id=80530


No that doesn't help. :D

To test with ActiveTcl 8.5,
be sure your TCLLIBPATH environment
variable is set so it can find
all the packages that got installed
with your ActiveTcl 8.4.




Date: 2006-05-09 13:02
Sender: ctasada

Logged In: YES
user_id=340696

I've just tried the same code in the ActiveTcl 8.5b5 base
executable without Tk (base-tcl8.5-thread-win32-ix86.exe)

And I get the next error:
can't find package vfs
while executing
"package require vfs"
(file
"c:/Tcl/bin/base-tcl8.5-thread-win32-ix86.exe/lib/vfs/mk4vfs.tcl"
line
21)
invoked from within
"source
c:/Tcl/bin/base-tcl8.5-thread-win32-ix86.exe/lib/vfs/mk4vfs.tcl"
("package ifneeded vfs::mk4 1.10" script)
invoked from within
"package require vfs::mk4"

Hope it helps.


Date: 2006-05-08 12:47
Sender: ctasada

Logged In: YES
user_id=340696

I've exactly the same problem running the ActiveTcl 8.5b5
(ActiveTcl8.5.0.0b5.261540-win32-ix86-threaded.exe)

Running from a clean installation.


Date: 2006-04-12 15:17
Sender: dgpProject Admin

Logged In: YES
user_id=80530


there are few differences
between wish and tclsh+[package require Tk]
and [console] is one of them.
[console] also does channel stuff,
so seemed like a good candidate
for the blame, but sounds less likely now.

some stack tracing and looking into
tclvfs, mkfs, et.c are in order.


Date: 2006-04-12 07:31
Sender: ecky-l

Logged In: YES
user_id=1345135

It has no effect. I doubt that it has to do with the builtin
console at all (although I don't know). My intention is that
it is more a problem of vfs channels plus channel handling
in wish.
I should post the bug in the starkit mailing list as well
and see what JCW says.



Date: 2006-04-11 18:41
Sender: dgpProject Admin

Logged In: YES
user_id=80530


Please try replacing

catch {console show}

with

catch {rename console {}}

and see what effect that has.


Date: 2006-04-11 16:38
Sender: ecky-l

Logged In: YES
user_id=1345135

All of it was done with the recent ActiveTcl 8.4.12, which
includes all the corresponding packages.

I believe:
- Tcl and Tk are version 8.4.12 (ActiveTcl).
- vfs version 1.3
- vfs::mk4 version 1.10



Date: 2006-04-11 12:13
Sender: dgpProject Admin

Logged In: YES
user_id=80530


Need version numbers on all
software involved.


Attached Files ( 3 )

Filename Description Download
console.diff Download
refcount.tcl test script Download
vfs-stdchan.patch patch to vfs to work around core std chan inheritance weirdness Download

Changes ( 26 )

Field Old Value Date By
File Added 179419: console.diff 2006-05-26 19:44 hobbs
close_date - 2006-05-26 19:44 hobbs
resolution_id Accepted 2006-05-26 19:44 hobbs
status_id Open 2006-05-26 19:44 hobbs
resolution_id None 2006-05-23 20:53 vincentdarley
assigned_to vincentdarley 2006-05-23 20:53 vincentdarley
File Added 177431: vfs-stdchan.patch 2006-05-10 05:54 hobbs
assigned_to hobbs 2006-05-10 05:54 hobbs
File Added 177429: refcount.tcl 2006-05-10 05:06 hobbs
artifact_group_id obsolete: 8.4.12 2006-05-10 00:24 hobbs
status_id Pending 2006-05-10 00:20 hobbs
resolution_id Works For Me 2006-05-10 00:20 hobbs
close_date 2006-05-09 23:57 2006-05-10 00:20 hobbs
priority 5 2006-05-10 00:19 hobbs
close_date - 2006-05-09 23:57 hobbs
status_id Open 2006-05-09 23:57 hobbs
assigned_to andreas_kupries 2006-05-09 23:57 hobbs
resolution_id None 2006-05-09 23:57 hobbs
assigned_to vincentdarley 2006-04-21 22:49 vincentdarley
assigned_to dgp 2006-04-12 15:17 dgp
close_date 2006-04-11 12:13 2006-04-11 18:41 dgp
artifact_group_id None 2006-04-11 18:41 dgp
status_id Pending 2006-04-11 18:41 dgp
assigned_to hobbs 2006-04-11 12:13 dgp
close_date - 2006-04-11 12:13 dgp
status_id Open 2006-04-11 12:13 dgp