summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--generic/tclEvent.c15
-rw-r--r--tests/event.test19
3 files changed, 33 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index bbbb621..0a38290 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2007-03-12 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclEvent.c (HandleBgErrors): Make efficient private copy
+ * tests/event.test (event-5.3): of the command prefix for the interp's
+ background error handling command to avoid panics due to pointers
+ to memory invalid after shimmering. [Bug 1670155]
+
* generic/tclNamesp.c (NsEnsembleImplementationCmd): Make efficient
* tests/namespace.test (namespace-42.8): private copy of the
command prefix as we invoke the command appropriate to a particular
diff --git a/generic/tclEvent.c b/generic/tclEvent.c
index 8c0c34c..2f03444 100644
--- a/generic/tclEvent.c
+++ b/generic/tclEvent.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclEvent.c,v 1.69 2006/11/13 08:23:07 das Exp $
+ * RCS: @(#) $Id: tclEvent.c,v 1.70 2007/03/12 19:28:49 dgp Exp $
*/
#include "tclInt.h"
@@ -200,11 +200,16 @@ HandleBgErrors(
int code, prefixObjc;
Tcl_Obj **prefixObjv, **tempObjv;
+ /*
+ * Note we copy the handler command prefix each pass through, so
+ * we do support one handler setting another handler.
+ */
+
+ Tcl_Obj *copyObj = TclListObjCopy(NULL, assocPtr->cmdPrefix);
+
errPtr = assocPtr->firstBgPtr;
- Tcl_IncrRefCount(assocPtr->cmdPrefix);
- Tcl_ListObjGetElements(NULL, assocPtr->cmdPrefix, &prefixObjc,
- &prefixObjv);
+ Tcl_ListObjGetElements(NULL, copyObj, &prefixObjc, &prefixObjv);
tempObjv = (Tcl_Obj **) ckalloc((prefixObjc+2)*sizeof(Tcl_Obj *));
memcpy(tempObjv, prefixObjv, prefixObjc*sizeof(Tcl_Obj *));
tempObjv[prefixObjc] = errPtr->errorMsg;
@@ -216,7 +221,7 @@ HandleBgErrors(
* Discard the command and the information about the error report.
*/
- Tcl_DecrRefCount(assocPtr->cmdPrefix);
+ Tcl_DecrRefCount(copyObj);
Tcl_DecrRefCount(errPtr->errorMsg);
Tcl_DecrRefCount(errPtr->returnOpts);
assocPtr->firstBgPtr = errPtr->nextPtr;
diff --git a/tests/event.test b/tests/event.test
index e2553d6..101a17e 100644
--- a/tests/event.test
+++ b/tests/event.test
@@ -9,7 +9,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: event.test,v 1.23 2006/11/27 20:16:03 kennykb Exp $
+# RCS: @(#) $Id: event.test,v 1.24 2007/03/12 19:28:50 dgp Exp $
package require tcltest 2
namespace import -force ::tcltest::*
@@ -188,6 +188,23 @@ test event-5.2 {Tcl_BackgroundError, HandleBgErrors procedures} {
rename bgerror {}
set x
} {{a simple error}}
+test event-5.3 {HandleBgErrors: [Bug 1670155]} -setup {
+ variable x
+ proc demo args {variable x done}
+ variable target [list [namespace which demo] x]
+ proc trial args {variable target; string length $target}
+ trace add execution demo enter [namespace code trial]
+ variable save [interp bgerror {}]
+ interp bgerror {} $target
+} -body {
+ after 0 {error bar}
+ vwait [namespace which -variable x]
+} -cleanup {
+ interp bgerror {} $save
+ unset x target save
+ rename demo {}
+ rename trial {}
+} -result {}
test event-6.1 {BgErrorDeleteProc procedure} {
catch {interp delete foo}