| Ticket UUID: | 1338280 | ||
| Title: | unset traces during namespace delete misbehave | ||
| Type: | Bug | Created on: | 2005-10-26 09:53:00 |
| Submitter: | msofer | Assigned to: | msofer |
| Subsystem: | 07. Variables | Severity: | |
| Priority: | 9 Immediate | Last modified: | 2005-11-04 09:14:57 |
| Status: | Closed | Closed by: | msofer |
| Resolution: | Fixed | Closed on: | 2005-11-04 02:14:57 |
| Version: | obsolete: 8.4.11 | ||
| 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-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. 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-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.
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-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 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. 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-02 22:38:46:
File Added - 154768: 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-03 00:10:19:
File Added - 154778: 1338280-84.patch dgp added on 2005-11-03 00:10:20:
File Deleted - 154768: 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. | ||||
Attachments:
- 1338280-84.patch [download] added by dgp on 2005-11-03 00:10:18. [details]
- 1338280.patch [download] added by dgp on 2005-11-01 02:25:10. [details]
