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:
- trace.patch [download] added by dgp on 2001-08-23 22:53:10. [details]