diff options
Diffstat (limited to 'doc/trace.n')
-rw-r--r-- | doc/trace.n | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/doc/trace.n b/doc/trace.n new file mode 100644 index 0000000..5482e59 --- /dev/null +++ b/doc/trace.n @@ -0,0 +1,426 @@ +'\" +'\" Copyright (c) 1993 The Regents of the University of California. +'\" Copyright (c) 1994-1996 Sun Microsystems, Inc. +'\" Copyright (c) 2000 Ajuba Solutions. +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH trace n "8.4" Tcl "Tcl Built-In Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +trace \- Monitor variable accesses, command usages and command executions +.SH SYNOPSIS +\fBtrace \fIoption\fR ?\fIarg arg ...\fR? +.BE +.SH DESCRIPTION +.PP +This command causes Tcl commands to be executed whenever certain operations are +invoked. The legal \fIoption\fRs (which may be abbreviated) are: +.TP +\fBtrace add \fItype name ops ?args?\fR +Where \fItype\fR is \fBcommand\fR, \fBexecution\fR, or \fBvariable\fR. +.RS +.TP +\fBtrace add command\fR \fIname ops commandPrefix\fR +. +Arrange for \fIcommandPrefix\fR to be executed (with additional arguments) +whenever command \fIname\fR is modified in one of the ways given by the list +\fIops\fR. \fIName\fR will be resolved using the usual namespace resolution +rules used by commands. If the command does not exist, an error will be +thrown. +.RS +.PP +\fIOps\fR indicates which operations are of interest, and is a list of +one or more of the following items: +.TP +\fBrename\fR +. +Invoke \fIcommandPrefix\fR whenever the traced command is renamed. Note that +renaming to the empty string is considered deletion, and will not be traced +with +.QW \fBrename\fR . +.TP +\fBdelete\fR +. +Invoke \fIcommandPrefix\fR when the traced command is deleted. Commands can be +deleted explicitly by using the \fBrename\fR command to rename the command to +an empty string. Commands are also deleted when the interpreter is deleted, +but traces will not be invoked because there is no interpreter in which to +execute them. +.PP +When the trace triggers, depending on the operations being traced, a number of +arguments are appended to \fIcommandPrefix\fR so that the actual command is as +follows: +.PP +.CS +\fIcommandPrefix oldName newName op\fR +.CE +.PP +\fIOldName\fR and \fInewName\fR give the traced command's current (old) name, +and the name to which it is being renamed (the empty string if this is a +.QW delete +operation). +\fIOp\fR indicates what operation is being performed on the +command, and is one of \fBrename\fR or \fBdelete\fR as +defined above. The trace operation cannot be used to stop a command +from being deleted. Tcl will always remove the command once the trace +is complete. Recursive renaming or deleting will not cause further traces +of the same type to be evaluated, so a delete trace which itself +deletes the command, or a rename trace which itself renames the +command will not cause further trace evaluations to occur. +Both \fIoldName\fR and \fInewName\fR are fully qualified with any namespace(s) +in which they appear. +.RE +.TP +\fBtrace add execution\fR \fIname ops commandPrefix\fR +. +Arrange for \fIcommandPrefix\fR to be executed (with additional arguments) +whenever command \fIname\fR is executed, with traces occurring at the points +indicated by the list \fIops\fR. \fIName\fR will be resolved using the usual +namespace resolution rules used by commands. If the command does not exist, +an error will be thrown. +.RS +.PP +\fIOps\fR indicates which operations are of interest, and is a list of +one or more of the following items: +.TP +\fBenter\fR +Invoke \fIcommandPrefix\fR whenever the command \fIname\fR is executed, +just before the actual execution takes place. +.TP +\fBleave\fR +Invoke \fIcommandPrefix\fR whenever the command \fIname\fR is executed, +just after the actual execution takes place. +.TP +\fBenterstep\fR +. +Invoke \fIcommandPrefix\fR for every Tcl command which is executed from the +start of the execution of the procedure \fIname\fR until that +procedure finishes. \fICommandPrefix\fR is invoked just before the actual +execution of the Tcl command being reported takes place. For example +if we have +.QW "proc foo {} { puts \N'34'hello\N'34' }" , +then an \fIenterstep\fR trace would be invoked just before +.QW "\fIputs \N'34'hello\N'34'\fR" +is executed. +Setting an \fIenterstep\fR trace on a command \fIname\fR that does not refer +to a procedure will not result in an error and is simply ignored. +.TP +\fBleavestep\fR +. +Invoke \fIcommandPrefix\fR for every Tcl command which is executed from the +start of the execution of the procedure \fIname\fR until that +procedure finishes. \fICommandPrefix\fR is invoked just after the actual +execution of the Tcl command being reported takes place. +Setting a \fIleavestep\fR trace on a command \fIname\fR that does not refer to +a procedure will not result in an error and is simply ignored. +.PP +When the trace triggers, depending on the operations being traced, a +number of arguments are appended to \fIcommandPrefix\fR so that the actual +command is as follows: +.PP +For \fBenter\fR and \fBenterstep\fR operations: +.PP +.CS +\fIcommandPrefix command-string op\fR +.CE +.PP +\fICommand-string\fR gives the complete current command being +executed (the traced command for a \fBenter\fR operation, an +arbitrary command for a \fBenterstep\fR operation), including +all arguments in their fully expanded form. +\fIOp\fR indicates what operation is being performed on the +command execution, and is one of \fBenter\fR or \fBenterstep\fR as +defined above. The trace operation can be used to stop the +command from executing, by deleting the command in question. Of +course when the command is subsequently executed, an +.QW "invalid command" +error will occur. +.PP +For \fBleave\fR and \fBleavestep\fR operations: +.PP +.CS +\fIcommandPrefix command-string code result op\fR +.CE +.PP +\fICommand-string\fR gives the complete current command being +executed (the traced command for a \fBenter\fR operation, an +arbitrary command for a \fBenterstep\fR operation), including +all arguments in their fully expanded form. +\fICode\fR gives the result code of that execution, and \fIresult\fR +the result string. +\fIOp\fR indicates what operation is being performed on the +command execution, and is one of \fBleave\fR or \fBleavestep\fR as +defined above. +Note that the creation of many \fBenterstep\fR or +\fBleavestep\fR traces can lead to unintuitive results, since the +invoked commands from one trace can themselves lead to further +command invocations for other traces. +.PP +\fICommandPrefix\fR executes in the same context as the code that invoked +the traced operation: thus the \fIcommandPrefix\fR, if invoked from a +procedure, will have access to the same local variables as code in the +procedure. This context may be different than the context in which the trace +was created. If \fIcommandPrefix\fR invokes a procedure (which it normally +does) then the procedure will have to use \fBupvar\fR or \fBuplevel\fR +commands if it wishes to access the local variables of the code which invoked +the trace operation. +.PP +While \fIcommandPrefix\fR is executing during an execution trace, traces +on \fIname\fR are temporarily disabled. This allows the \fIcommandPrefix\fR +to execute \fIname\fR in its body without invoking any other traces again. +If an error occurs while executing the \fIcommandPrefix\fR, then the +command \fIname\fR as a whole will return that same error. +.PP +When multiple traces are set on \fIname\fR, then for \fIenter\fR +and \fIenterstep\fR operations, the traced commands are invoked +in the reverse order of how the traces were originally created; +and for \fIleave\fR and \fIleavestep\fR operations, the traced +commands are invoked in the original order of creation. +.PP +The behavior of execution traces is currently undefined for a command +\fIname\fR imported into another namespace. +.RE +.TP +\fBtrace add variable\fI name ops commandPrefix\fR +Arrange for \fIcommandPrefix\fR to be executed whenever variable \fIname\fR +is accessed in one of the ways given by the list \fIops\fR. \fIName\fR may +refer to a normal variable, an element of an array, or to an array +as a whole (i.e. \fIname\fR may be just the name of an array, with no +parenthesized index). If \fIname\fR refers to a whole array, then +\fIcommandPrefix\fR is invoked whenever any element of the array is +manipulated. If the variable does not exist, it will be created but +will not be given a value, so it will be visible to \fBnamespace which\fR +queries, but not to \fBinfo exists\fR queries. +.RS +.PP +\fIOps\fR indicates which operations are of interest, and is a list of +one or more of the following items: +.TP +\fBarray\fR +Invoke \fIcommandPrefix\fR whenever the variable is accessed or modified via +the \fBarray\fR command, provided that \fIname\fR is not a scalar +variable at the time that the \fBarray\fR command is invoked. If +\fIname\fR is a scalar variable, the access via the \fBarray\fR +command will not trigger the trace. +.TP +\fBread\fR +Invoke \fIcommandPrefix\fR whenever the variable is read. +.TP +\fBwrite\fR +Invoke \fIcommandPrefix\fR whenever the variable is written. +.TP +\fBunset\fR +Invoke \fIcommandPrefix\fR whenever the variable is unset. Variables +can be unset explicitly with the \fBunset\fR command, or +implicitly when procedures return (all of their local variables +are unset). Variables are also unset when interpreters are +deleted, but traces will not be invoked because there is no +interpreter in which to execute them. +.PP +When the trace triggers, three arguments are appended to +\fIcommandPrefix\fR so that the actual command is as follows: +.PP +.CS +\fIcommandPrefix name1 name2 op\fR +.CE +.PP +\fIName1\fR and \fIname2\fR give the name(s) for the variable +being accessed: if the variable is a scalar then \fIname1\fR +gives the variable's name and \fIname2\fR is an empty string; +if the variable is an array element then \fIname1\fR gives the +name of the array and name2 gives the index into the array; +if an entire array is being deleted and the trace was registered +on the overall array, rather than a single element, then \fIname1\fR +gives the array name and \fIname2\fR is an empty string. +\fIName1\fR and \fIname2\fR are not necessarily the same as the +name used in the \fBtrace variable\fR command: the \fBupvar\fR +command allows a procedure to reference a variable under a +different name. +\fIOp\fR indicates what operation is being performed on the +variable, and is one of \fBread\fR, \fBwrite\fR, or \fBunset\fR as +defined above. +.PP +\fICommandPrefix\fR executes in the same context as the code that invoked +the traced operation: if the variable was accessed as part of a Tcl +procedure, then \fIcommandPrefix\fR will have access to the same local +variables as code in the procedure. This context may be different +than the context in which the trace was created. If \fIcommandPrefix\fR +invokes a procedure (which it normally does) then the procedure will +have to use \fBupvar\fR or \fBuplevel\fR if it wishes to access the +traced variable. Note also that \fIname1\fR may not necessarily be +the same as the name used to set the trace on the variable; +differences can occur if the access is made through a variable defined +with the \fBupvar\fR command. +.PP +For read and write traces, \fIcommandPrefix\fR can modify the variable to +affect the result of the traced operation. If \fIcommandPrefix\fR modifies +the value of a variable during a read or write trace, then the new +value will be returned as the result of the traced operation. The +return value from \fIcommandPrefix\fR is ignored except that if it returns +an error of any sort then the traced operation also returns an error +with the same error message returned by the trace command (this +mechanism can be used to implement read-only variables, for example). +For write traces, \fIcommandPrefix\fR is invoked after the variable's value +has been changed; it can write a new value into the variable to +override the original value specified in the write operation. To +implement read-only variables, \fIcommandPrefix\fR will have to restore the +old value of the variable. +.PP +While \fIcommandPrefix\fR is executing during a read or write trace, traces +on the variable are temporarily disabled. This means that reads and +writes invoked by \fIcommandPrefix\fR will occur directly, without invoking +\fIcommandPrefix\fR (or any other traces) again. However, if +\fIcommandPrefix\fR unsets the variable then unset traces will be invoked. +.PP +When an unset trace is invoked, the variable has already been deleted: +it will appear to be undefined with no traces. If an unset occurs +because of a procedure return, then the trace will be invoked in the +variable context of the procedure being returned to: the stack frame +of the returning procedure will no longer exist. Traces are not +disabled during unset traces, so if an unset trace command creates a +new trace and accesses the variable, the trace will be invoked. Any +errors in unset traces are ignored. +.PP +If there are multiple traces on a variable they are invoked in order +of creation, most-recent first. If one trace returns an error, then +no further traces are invoked for the variable. If an array element +has a trace set, and there is also a trace set on the array as a +whole, the trace on the overall array is invoked before the one on the +element. +.PP +Once created, the trace remains in effect either until the trace is +removed with the \fBtrace remove variable\fR command described below, +until the variable is unset, or until the interpreter is deleted. +Unsetting an element of array will remove any traces on that element, +but will not remove traces on the overall array. +.PP +This command returns an empty string. +.RE +.RE +.TP +\fBtrace remove \fItype name opList commandPrefix\fR +Where \fItype\fR is either \fBcommand\fR, \fBexecution\fR or \fBvariable\fR. +.RS +.TP +\fBtrace remove command\fI name opList commandPrefix\fR +If there is a trace set on command \fIname\fR with the operations and +command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is +removed, so that \fIcommandPrefix\fR will never again be invoked. Returns +an empty string. If \fIname\fR does not exist, the command will throw +an error. +.TP +\fBtrace remove execution\fI name opList commandPrefix\fR +If there is a trace set on command \fIname\fR with the operations and +command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is +removed, so that \fIcommandPrefix\fR will never again be invoked. Returns +an empty string. If \fIname\fR does not exist, the command will throw +an error. +.TP +\fBtrace remove variable\fI name opList commandPrefix\fR +If there is a trace set on variable \fIname\fR with the operations and +command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is +removed, so that \fIcommandPrefix\fR will never again be invoked. Returns +an empty string. +.RE +.TP +\fBtrace info \fItype name\fR +Where \fItype\fR is either \fBcommand\fR, \fBexecution\fR or \fBvariable\fR. +.RS +.TP +\fBtrace info command\fI name\fR +Returns a list containing one element for each trace currently set on +command \fIname\fR. Each element of the list is itself a list +containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR +associated with the trace. If \fIname\fR does not have any traces set, +then the result of the command will be an empty string. If \fIname\fR +does not exist, the command will throw an error. +.TP +\fBtrace info execution\fI name\fR +Returns a list containing one element for each trace currently set on +command \fIname\fR. Each element of the list is itself a list +containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR +associated with the trace. If \fIname\fR does not have any traces set, +then the result of the command will be an empty string. If \fIname\fR +does not exist, the command will throw an error. +.TP +\fBtrace info variable\fI name\fR +Returns a list containing one element for each trace currently set on +variable \fIname\fR. Each element of the list is itself a list +containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR +associated with the trace. If \fIname\fR does not exist or does not +have any traces set, then the result of the command will be an empty +string. +.RE +.PP +For backwards compatibility, three other subcommands are available: +.RS +.TP +\fBtrace variable \fIname ops command\fR +This is equivalent to \fBtrace add variable \fIname ops command\fR. +.TP +\fBtrace vdelete \fIname ops command\fR +This is equivalent to \fBtrace remove variable \fIname ops command\fR +.TP +\fBtrace vinfo \fIname\fR +This is equivalent to \fBtrace info variable \fIname\fR +.RE +.PP +These subcommands are deprecated and will likely be removed in a +future version of Tcl. They use an older syntax in which \fBarray\fR, +\fBread\fR, \fBwrite\fR, \fBunset\fR are replaced by \fBa\fR, \fBr\fR, +\fBw\fR and \fBu\fR respectively, and the \fIops\fR argument is not a +list, but simply a string concatenation of the operations, such as +\fBrwua\fR. +.SH EXAMPLES +.PP +Print a message whenever either of the global variables \fBfoo\fR and +\fBbar\fR are updated, even if they have a different local name at the +time (which can be done with the \fBupvar\fR command): +.PP +.CS +proc tracer {varname args} { + upvar #0 $varname var + puts "$varname was updated to be \e"$var\e"" +} +\fBtrace add\fR variable foo write "tracer foo" +\fBtrace add\fR variable bar write "tracer bar" +.CE +.PP +Ensure that the global variable \fBfoobar\fR always contains the +product of the global variables \fBfoo\fR and \fBbar\fR: +.PP +.CS +proc doMult args { + global foo bar foobar + set foobar [expr {$foo * $bar}] +} +\fBtrace add\fR variable foo write doMult +\fBtrace add\fR variable bar write doMult +.CE +.PP +Print a trace of what commands are executed during the processing of a Tcl +procedure: +.PP +.CS +proc x {} { y } +proc y {} { z } +proc z {} { puts hello } +proc report args {puts [info level 0]} +\fBtrace add\fR execution x enterstep report +x + \(-> \fIreport y enterstep\fR + \fIreport z enterstep\fR + \fIreport {puts hello} enterstep\fR + \fIhello\fR +.CE +.SH "SEE ALSO" +set(n), unset(n) +.SH KEYWORDS +read, command, rename, variable, write, trace, unset +.\" Local Variables: +.\" mode: nroff +.\" End: |