Ticket UUID: | 1338280 | |||
Title: | unset traces during namespace delete misbehave | |||
Type: | Bug | Version: | obsolete: 8.4.11 | |
Submitter: | msofer | Created on: | 2005-10-26 09:53:00 | |
Subsystem: | 07. Variables | Assigned To: | msofer | |
Priority: | 9 Immediate | Severity: | ||
Status: | Closed | Last Modified: | 2005-11-04 09:14:57 | |
Resolution: | Fixed | Closed By: | msofer | |
Closed on: | 2005-11-04 02:14:57 | |||
Description: |
(neuronstorm reports in clt: http://groups.google.com/group/comp.lang.tcl/browse_frm/thread/91073af364234a81/3a1aa30e489f3eb0#3a1aa30e489f3eb0 The following script demonstrates an invalid result (empty string element in list) from [info vars ?pattern?] during unset traces called during [namespace delete]. ---- namespace eval ::ref {} set ::ref::var1 AAA trace add variable ::ref::var1 {unset} [list doTrace] set ::ref::var2 BBB trace add variable ::ref::var2 {unset} [list doTrace] proc doTrace {vtraced vidx op} { puts stdout "'[info vars ::ref::*]'" } namespace delete ::ref puts stdout "'[info vars ::ref::*]'" ---- Output on windows Tcl 8.5a4 is: '::ref::var1 ::ref::var2' '{} ::ref::var2' '' Output on windows Tcl 8.4.5 is: '::ref::var1 ::ref::var2' '::ref::var2' '' Tcl8.4.7 behaves like 8.4.5, core-8-4-branch like 8.5a4 | |||
User Comments: |
msofer added on 2005-11-04 09:14:57:
Logged In: YES user_id=148712 Attached 8.4 patch adapted and committed to both branches. dgp added on 2005-11-03 00:10:20: File Deleted - 154768: dgp added on 2005-11-03 00:10:19: File Added - 154778: 1338280-84.patch dgp added on 2005-11-03 00:10:17: Logged In: YES user_id=80530 that patch contained a memory leak. here's the corrected replacement. dgp added on 2005-11-02 22:38:46: File Added - 154768: 1338280-84.patch dgp added on 2005-11-02 22:38:42: Logged In: YES user_id=80530 Here's a different patch (against 8-4-branch) without the incompatibility of the first. Please look it over. dgp added on 2005-11-01 11:26:53: Logged In: YES user_id=80530 the patch does introduce a script-visible change, yes. it's also a simple change that fixes this bug and allegedly 1337229. Neither the tcl nor the tcllib test suite care about the change. If something does care, then let's think harder about this, but not until we find something that does care. Crafting a fix for these bugs other than the one attached here will be very, very tricky indeed. Unless we delay variable unset traces until the point where the namespace variables are no longer accessible, then the access must go somewhere, and we're left with the recursive task of cleaning *that* up. I fear we may already have that problem with command delete traces. msofer added on 2005-11-01 04:45:32: Logged In: YES user_id=148712 Patch not committed: it contradicts the comment in TclTeardownNamespace: /* * Start by destroying the namespace's variable table, * since variables might trigger traces. */ In particular, the patch changes the behaviour of the script: namespace eval a { proc p {} {puts hi} trace add variable x unset {a::p;#} set x 1 } namespace delete a which prints 'hi' before the patch, and does not after the patch. Note that these comments in the source are the only documentation about the ordering of operations during namespace deletion. dgp added on 2005-11-01 02:25:10: File Added - 154563: 1338280.patch Logged In: YES user_id=80530 attached patch corrects the reported problem and passes the test suite. msofer added on 2005-10-30 02:02:53: Logged In: YES user_id=148712 The fundamental problem is that, when a variable is unset due to its namespace being deleted, the variable exists while the unset trace is running: namespace eval a {trace add variable x unset {puts [catch {set ::a::x}];#}; set x 1} 1 % unset a::x 1 % namespace eval a {trace add variable x unset {puts [catch {set ::a::x}];#}; set x 1} 1 % namespace delete a 0 This is a very old bug - just verified that Tcl8.3.4 has it too. It is probably also the cause of Bug 1337229. msofer added on 2005-10-30 01:58:07: Logged In: YES user_id=148712 As the order in which the variables are deleted is not specified, this script has been modified an added to the testsuite as Test trace-18.4: namespace eval ::ref {} set ::ref::var1 AAA trace add variable ::ref::var1 unset doTrace set ::ref::var2 BBB trace add variable ::ref::var2 {unset} doTrace proc doTrace {vtraced vidx op} { global info append info [catch {set ::$vtraced}][llength [info vars ::ref::*]] } set info {} namespace delete ::ref rename doTrace {} set info Note that the returned value is 0201 up to 8.4.7, and 0202 for HEAD and 8-4-branch. Note also that the *correct* return value is 1110 - as a variable should not exist when it's unset trace is running. msofer added on 2005-10-26 19:52:56: Logged In: YES user_id=148712 On the basis of which versions are buggy, this is presumed to be caused by the 2004-05-22 commit. |
