Tcl Source Code

View Ticket
Login
Ticket UUID: 402501
Title: Fix for Bug 119393 ([trace remove] & Tcl_Preserve)
Type: Patch Version: None
Submitter: dgp Created on: 2000-11-24 16:43:28
Subsystem: 18. Commands M-Z Assigned To: dkf
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2001-11-19 22:27:04
Resolution: Invalid Closed By: dkf
    Closed on: 2001-11-19 15:27:04
User Comments: dkf added on 2001-11-19 22:27:03:
Logged In: YES 
user_id=79902

219393 is now fixed, and was fixed by a new API (TIP#68)

dgp added on 2001-08-23 22:53:10:

File Deleted - 2326: 



File Added - 9898: trace.patch

Logged In: YES 
user_id=80530

Updated patch for current HEAD.

It's still the wrong patch for fixing 219393,
but it can be useful for testing some things.

dgp added on 2001-02-28 06:05:18:
Logged In: YES 
user_id=80530

The fix I had in mind for this has two steps.

1. Modify CallTraces() (in generic/tclVar.c) so that it
can recognize a special value

#define TCL_TRACE_ERROR_MESSAGE_IN_INTERP_RESULT 0x1

returned from a trace procedure as a signal that the error
message should be retrieved from
Tcl_GetStringResult(interp).

That change would require a TIP.

2. Make use of the new interface by having TraceVarInfo()
stick error messages in the interp result and return
TCL_TRACE_ERROR_MESSAGE_IN_INTERP_RESULT when there is
an error in the evaluation of the trace script.  Then
get rid of the errMsg field in the TraceVarInfo struct.

This seems to me to be the safe way to get an error message
that is not a static string back to Tcl_TraceVar().
Similar changes/fixes may also be needed in
CallCommandTraces(), etc.

This approach may go against the RESTRICTIONS section of
Tcl_TraceVar(3), though.  That section instructs all trace
procedures to save and restore interp->result before 
returning.  But why impose that burden on every trace
procedure?  Why isn't CallTraces() itself saving and
restoring the interpreter result?

dgp added on 2000-11-28 03:51:53:
Looks like the whole TraceVarInfo() routine needs a
rewrite.  By the requirements of Tcl_TraceVar(),
TraceVarInfo() is supposed to return NULL on success,
or a pointer to a *static* character string containing
an error message on failure.  When the trace script
returns an error, though, TraceVarInfo is returning the
pointer tvarPtr->errMsg, which is dynamically allocated
and which assumes the structure *tvarPtr still exists.
This means TraceVarInfo() is incapable of properly handling
a trace script that both returns an error and deletes
the trace, because then there's nowhere for the error
message to live.

dgp added on 2000-11-25 00:58:31:
This patch has a memory leak, exhibited by
the following script:

proc Hare {old args} {
    trace vdelete ::bunny w [list Hare $old]
    trace variable ::bunny w [list Hare $::bunny]
    error "FOO"
}
set bunny Bugs
trace variable bunny w [list Hare $bunny]
while {1} {catch { set bunny Easter}}

Attachments: