ASPN ActiveState Programmer Network
  ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups | Web Services
SEARCH

Reference
ActiveTcl 8.5
ActiveTcl 8.5.4.0 User Guide
ActiveTcl 8.5.4.0 Documentation Index
Tutorial
Adding & Deleting members of a list
Adding new commands to Tcl - proc
Assigning values to variables
Associative Arrays
Building reusable libraries - packages and namespaces
Changing Working Directory - cd, pwd
Channel I/O: socket, fileevent, vwait
Child interpreters
Command line arguments and environment strings
Creating Commands - eval
Debugging & Errors - errorInfo errorCode catch error return
Evaluation & Substitutions 1: Grouping arguments with ""
Evaluation & Substitutions 2: Grouping arguments with {}
Evaluation & Substitutions 3: Grouping arguments with []
File Access 101
Information about Files - file, glob
Information about procs - info
Introduction
Invoking Subprocesses from Tcl - exec, open
Learning the existence of commands and variables ? - info
Leftovers - time, unset
Looping 101 - While loop
Looping 102 - For and incr
Modifying Strings - tolower, toupper, trim, format
Modularization - source
More channel I/O - fblocked & fconfigure
More command construction - format, list
More Debugging - trace
More Examples Of Regular Expressions
More list commands - lsearch, lsort, lrange
More On Arrays - Iterating and use in procedures
More Quoting Hell - Regular Expressions 102
Numeric Comparisons 101 - if
Regular Expressions 101
Results of a command - Math 101
Simple pattern matching - "globbing"
Simple Text Output
State of the interpreter - info
String comparisons - compare match first last wordend
String Subcommands - length index range
Substitution without evaluation - format, subst
Tcl Data Structures 101 - The list
Textual Comparison - switch
Time and Date - clock
Variable scope - global and upvar
Variations in proc arguments and return values

MyASPN >> Reference >> ActiveTcl 8.5 >> ActiveTcl 8.5.4.0 User Guide >> ActiveTcl 8.5.4.0 Documentation Index >> Tutorial
ActiveTcl 8.5 documentation

More Debugging - trace

When you are debugging Tcl code, sometimes it's useful to be able to trace either the execution of the code, or simply inspect the state of a variable when various things happen to it. The trace command provides these facilities. It is a very powerful command that can be used in many interesting ways. It also risks being abused, and can lead to very difficult to understand code if it is used improperly (for instance, variables seemingly changing magically), so use it with care.

There are three principle operations that may be performed with the trace command:

  • add, which has the general form: trace add type ops ?args?
  • info, which has the general form: trace info type name
  • remove, which has the general form: trace remove type name opList command

Which are for adding traces, retrieving information about traces, and removing traces, respectively. Traces can be added to three kinds of "things":

  • variable - Traces added to variables are called when some event occurs to the variable, such as being written to or read.
  • command - Traces added to commands are executed whenever the named command is renamed or deleted.
  • execution - Traces on "execution" are called whenever the named command is run.

Traces on variables are invoked on four separate conditions - when a variable is accessed or modified via the array command, when the variable is read or written, or when it's unset. For instance, to set a trace on a variable so that when it's written to, the value doesn't change, you could do this:

proc vartrace {oldval varname element op} {
    upvar $varname localvar
    set localvar $oldval
}

set tracedvar 1
trace add variable tracedvar write [list vartrace $tracedvar]

set tracedvar 2
puts "tracedvar is $tracedvar"

In the above example, we create a proc that takes four arguments. We supply the first, the old value of the variable, because write traces are triggered after the variable's value has already been changed, so we need to preserve the original value ourselves. The other three arguments are the variable's name, the element name if the variable is an array (which it isn't in our example), and the operation to trace - in this case, write. When the trace is called, we simply set the variable's value back to its old value. We could also do something like generate an error, thus warning people that this variable shouldn't be written to. Infact, this would probably be better. If someone else is attempting to understand your program, they could become quite confused when they find that a simple set command no longer functions!

The command and execution traces are intended for expert users - perhaps those writing debuggers for Tcl in Tcl itself - and are therefore not covered in this tutorial, see the trace man page for further information.


Example

proc traceproc {variableName arrayElement operation} {
    set op(write) Write
    set op(unset) Unset
    set op(read) Read

    set level [info level]
    incr level -1
    if {$level > 0} {
    set procid [info level $level]
    } else {
    set procid "main"
    }

    if {![string match $arrayElement ""]} {
    puts "TRACE: $op($operation) $variableName($arrayElement) in $procid"
    } else {
    puts "TRACE: $op($operation) $variableName in $procid"
    }
}

proc testProc {input1 input2} {
    upvar $input1 i
    upvar $input2 j

    set i 2
    set k $j
}

trace add variable i1 write traceproc
trace add variable i2 read traceproc
trace add variable i2 write traceproc

set i2 "testvalue"

puts "\ncall testProc"
testProc i1 i2

puts "\nTraces on i1: [trace info variable i1]"
puts "Traces on i2: [trace info variable i2]\n"

trace remove variable i2 read traceproc
puts "Traces on i2 after vdelete: [trace info variable i2]"

puts "\ncall testProc again"
testProc i1 i2

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState 2004 All rights reserved