summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2001-12-07 13:55:59 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2001-12-07 13:55:59 (GMT)
commite69719ee4125cc09779401e3dda6c4b67651d382 (patch)
treebe9d02ee7c40c6fd4919fc83c406315d3807c43d
parent6425a01b7a2896172c65f9883f0b56792a6fd263 (diff)
downloadtcl-e69719ee4125cc09779401e3dda6c4b67651d382.zip
tcl-e69719ee4125cc09779401e3dda6c4b67651d382.tar.gz
tcl-e69719ee4125cc09779401e3dda6c4b67651d382.tar.bz2
restored consistency in refCount accounting by array traces [Bug #4484339]
-rw-r--r--ChangeLog6
-rw-r--r--generic/tclVar.c6
-rw-r--r--tests/trace.test16
3 files changed, 24 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 737ecd4..2ae86b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-07 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclVar.c:
+ * tests/trace.test: restored consistency in refCount accounting by
+ array traces [Bug #4484339], submitted by Don Porter.
+
2001-12-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/parseExpr.test, tests/for.test, tests/expr.test:
diff --git a/generic/tclVar.c b/generic/tclVar.c
index 401e36b..134ca16 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -15,7 +15,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclVar.c,v 1.43 2001/12/05 20:43:58 msofer Exp $
+ * RCS: @(#) $Id: tclVar.c,v 1.44 2001/12/07 13:55:59 msofer Exp $
*/
#include "tclInt.h"
@@ -4514,6 +4514,9 @@ CallTraces(iPtr, arrayPtr, varPtr, part1, part2, flags, resultTypePtr)
}
varPtr->flags |= VAR_TRACE_ACTIVE;
varPtr->refCount++;
+ if (arrayPtr != NULL) {
+ arrayPtr->refCount++;
+ }
/*
* If the variable name hasn't been parsed into array name and
@@ -4556,7 +4559,6 @@ CallTraces(iPtr, arrayPtr, varPtr, part1, part2, flags, resultTypePtr)
iPtr->activeTracePtr = &active;
Tcl_Preserve((ClientData) iPtr);
if (arrayPtr != NULL && !(arrayPtr->flags & VAR_TRACE_ACTIVE)) {
- arrayPtr->refCount++;
active.varPtr = arrayPtr;
for (tracePtr = arrayPtr->tracePtr; tracePtr != NULL;
tracePtr = active.nextTracePtr) {
diff --git a/tests/trace.test b/tests/trace.test
index beab9c6..6a5cc88 100644
--- a/tests/trace.test
+++ b/tests/trace.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: trace.test,v 1.15 2001/12/05 20:43:58 msofer Exp $
+# RCS: @(#) $Id: trace.test,v 1.16 2001/12/07 13:55:59 msofer Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -56,6 +56,18 @@ proc traceCommand {oldName newName op} {
global info
set info [list $oldName $newName $op]
}
+
+test trace-0.0 {memory corruption in trace (Tcl Bug 484339)} {
+ # You may need Purify or Electric Fence to reliably
+ # see this one fail.
+ catch {unset z}
+ trace add variable z array {set z(foo) 1 ;#}
+ set res "names: [array names z]"
+ catch {unset ::z}
+ trace variable ::z w {unset ::z; error "memory corruption";#}
+ list [catch {set ::z 1} msg] $msg
+} {1 {can't set "::z": memory corruption}}
+
# Read-tracing on variables
test trace-1.1 {trace variable reads} {
@@ -913,7 +925,7 @@ test trace-15.3 {special list-handling in trace commands} {
trace add variable "x y z(a\n\{)" write traceProc
set "x y z(a\n\{)" 33
set info
-} "{x y z} a\\n\\{ write"
+} "{x y z} a\\n\\\{ write"
# Check for proper handling of unsets during traces.