TIP 32: Add Tcl_Obj-enabled counterpart to Tcl_CreateTrace

Author:         David Cuthbert <[email protected]>
Author:         Kevin Kenny <[email protected]>
State:          Final
Type:           Project
Vote:           Done
Created:        23-Mar-2001
Discussions-To: news:comp.lang.tcl
Keywords:       trace,Tcl_Obj
Tcl-Version:    8.4a4


This document proposes to add Tcl_Obj support for trace procedures written in C.


The Tcl_Obj system was introduced in version 8.0, making computations (potentially) much more efficient by eliminating many type conversions to and from strings. However, the trace API continues to require character strings in both command and variable traces.

In addition, the Tcl_CreateTrace function interacts rather badly with the bytecode compiler, since it forbids inlining of functions. Since many trace applications ignore the built-in functions that would have been inlined, this restriction is not needed by many applications. This TIP proposes to make it optional in the revised API.

The trace mechanism in the Tcl library has been underused for some time, partly because it is awkward. While the profiler, tracer and debugger from TclX and the debugger from Expect have seen some limited success, they are certainly not familiar to the majority of Tcl users.

The second author of this TIP has experimented with using the trace mechanism to build a profiler for Tcl that does not depend on source code instrumentation. His experience was that:

This TIP is an effort to rationalize the trace interface to avoid these difficulties.


The following functions shall be added to the Tcl core:

  1. Tcl_CreateObjTrace

     Tcl_Trace Tcl_CreateObjTrace ( Tcl_Interp*          interp,
                                    int                  level, 
                                    int                  flags,
                                    Tcl_CmdObjTraceProc* objProc,
                                    ClientData           clientData );

    The Tcl_CreateObjTrace function adds a trace to the Tcl evaluator. The interp argument is the Tcl interpreter for which tracing is being requested. The level argument is the maximum depth of recursive calls; when the execution depth of the interpreter exceeds this number, the trace callback does not execute. The objProc argument is the callback procedure to execute each time a Tcl command is evaluated; it is expected to have arguments and result type that match Tcl_CmdObjTraceProc below. The clientData argument is client data to pass to the objProc callback. Finally, the flags argument gives flags that control the tracing. Initially, the only flag supported will be TCL_ALLOW_INLINE_COMPILE. If this flag is set, the bytecode compiler is permitted to compile in-line code for the Tcl built-in commands; any command that has been compiled in-line will not be traced.

    The Tcl_CreateObjTrace function returns a trace token -- an object of opaque type that may be passed to Tcl_DeleteTrace to delete the trace.

    The Tcl_CmdObjTraceProc will have the following type signature.

        typedef int Tcl_CmdObjTraceProc( ClientData     clientData,
                                         Tcl_Interp*    interp,
                                         int            level,
                                         CONST char*    command,
                                         Tcl_Command    commandInfo,
                                         int            objc,
                                         Tcl_Obj *CONST objv[] );

    The clientData parameter is the client data that was passed to Tcl_CreateObjTrace. The interp parameter designates a Tcl interpreter. The level parameter specifies the execution level. The command parameter gives the raw UTF-8 text of the command being evaluated, before any substitutions have been performed. The commandInfo parameter is an opaque Tcl_Command object that gives information about the command. The objc and objv parameters are the command name and parameter vector after substitution.

    The trace procedure is expected to return a standard Tcl status return. If it returns TCL_OK, the command is evaluated normally. If it returns TCL_ERROR, evaluation of the command does not take place. The interpreter result is expected to contain an error message. If it returns any other status, such as TCL_BREAK, TCL_CONTINUE or TCL_RETURN, it is treated as if the command had done so.

  2. Tcl_GetCommandInfoFromToken and Tcl_SetCommandInfoFromToken

     Tcl_GetCommandInfoFromToken( Tcl_Command  token,
                              Tcl_CmdInfo* infoPtr );
     Tcl_SetCommandInfoFromToken( Tcl_Command        token,
                              CONST Tcl_CmdInfo* infoPtr );

    The Tcl_GetCommandInfoFromToken and Tcl_SetCommandInfoFromToken functions are precisely parallel to today's Tcl_GetCommandInfo and Tcl_SetCommandInfo procedures, except that they accept an opaque Tcl_Command object instead of a command name. They are provided so that trace procedures (and other extensions that have such an object) can adjust command information without having to go through two extra lookups in the command hash by applying Tcl_GetCommandInfo to the result of Tcl_GetCommandName.

Change History

10 February 2002 - Moved to Final Status with slight revisions in the names and arguments of Tcl_GetCommandInfoFromToken and Tcl_SetCommandInfoFromToken.

3 November 2001 - Reworked the entire TIP. Changed the object trace handling to work with Tcl_Command objects instead of command names. Removed the object-based variable trace procedures. Since Tcl variable names really are character strings and not Tcl objects, object-based variable trace procedures would be slower than the string-based ones.

30 March 2001 - Changed return value of objProc to a Tcl_Obj * instead of int (and using the interpreter result to indicate an error). This is more consistent with the current behavior (but without the bug). -dac


Copyright © 2000 by David Cuthbert. Distribution in whole or part, with or without annotations, is unlimited.

Copyright © 2001 by Kevin B. Kenny. Distribution in whole or part, with or without annotations, is unlimited.