Thanks to visit codestin.com
Credit goes to github.com

Skip to content

geoff1111/jdb.tcl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Small JimTcl debugger

Jdb.tcl is simple and small--the debugger proper (excluding comments and code implementing this help text, version information etc) is implemented in about 250 single lines of code.

Jdb.tcl can be used at at the command line or in JimTcl tests (tcltest) using the testing.tcl helper script. Command line synopsis:

./jdb.tcl --help
./jdb.tcl --version
./jdb.tcl [-|JDB_CMD_FILE] JIM_SCRIPT ?args ...?

Jdb.tcl ultimately creates an unknown command as the debugger. It redefines proc so that any JIM_SCRIPT proc will be named _cmd instead of cmd. Most builtins are renamed from cmd to _cmd.

(JIM_SCRIPT cannot define unknown and cannot redefine proc. Thus jdb.tcl cannot be used to debug itself, because it redefines proc and unknown.)

Empirically, the author determined that certain JimTcl builtins cannot be renamed on a Debian system, or if renamed, the functionality of jdb.tcl is impaired. These are: if, pid, regexp, tailcall, stdin, stdout and stderr. (You may need to perform tests on your system if any of these need to be renamed, and success is not guaranteed.) This issue is significant insofar as it is not possible to break on these particular builtins.

The debugger control commands si (step in), so (step out), n (next), c (continue) and q (quit debugger) directly control debugger movement through JIM_SCRIPT. Typing Enter repeats the last debugger control command (except for q, since it causes the debugger to exit).

Breakpoints and breakconditions are set with b and bc respectively and either can cause execution of JIM_SCRIPT to pause and for control to be returned to the user at the debugger prompt. bcr is helpful to reset the break condition list. In interactive mode, the debugger will break on the commands exit or error allowing further investigation of problems before the debugger exits. In non-interactive mode exit and error are not automatically set as break conditions, so the debugger will exit if these are met and are not manually set as break conditions. (This latter behavior is generally appropriate for batch mode).

All other debugger commands display information. For instance, the debugger command h (or ?) display general help consisting of a synopsis of all debugger commands. Specific help on subcommand "subcmd" is available with h subcmd (or ? subcmd).

In addition to debugger control and display commands, any JimTcl command can be used at the debugger prompt, including exec, so debugging can extend to more complex JimTcl scripts such as webservers. Tcl commands can extend over multiple lines. Once the debugger reaches the point immediately prior to the webserver accepting a connection, curl could be invoked in the background at the debugger command prompt to connect:

exec curl 127.0.0.1:8080 &

Jdb.tcl relies on array ::debug internally. Use of ::debug enables various arbitrary functions to be achieved. Peruse ::debug array initialization in the source of jdb.tcl to assess what ad hoc functions might be achievable.

When invoked, the debugger breaks at the first JimTcl command of JIM_SCRIPT using si (excluding JimTcl commands which cannot be renamed such as if, pid, etc).

Jdb.tcl reads from stdin (-) or a JDB_COMMAND_FILE to accept input (debugger commands) using array element ::debug(in). Command input is overwritten to file debug.history using file handle variable ::debug(out). To rerun the previous sequence of debugger commands, first change the name of debug.history so that the input is not overwritten as soon as jdb.tcl starts:

mv debug.history debug.history.in
./jdb.tcl debug.history.in JIMTCL_SCRIPT [ARG ...]

The debugger enters interactive mode after the last command in debug.history.in is executed. Command sequence files can be created with a text editor.

The format for specifying breakpoints in JIM_SCRIPT depends on whether they are at the toplevel or within a proc. Toplevel breakpoints use the format file:FILENAME:LINE. Breakpoints within a proc are formatted proc:PROCNAME:CMD_NUMBER. The CMD_NUMBER is the number of the command within the proc (including subcommands) counting from 1.

A constraint (optional) can be defined with a breakpoint for conditionality. The default constraint is 1 which causes a breakpoint to be non-conditional. A breakpoint constraint is evaluated as an expr expression and should be enclosed in braces if it contains variables or commands. The format for a breakpoint with a constraint is:

b proc:PROCNAME:CMD_NO {constraint expression}

A breakcondition can be specified as follows:

bc {$::debug(tclcmd) eq "puts"}

The break condition is evaluated as a JimTcl expr. Break conditions are versatile. For example they can break execution when a variable is given a non-empty value (or a specific value):

bc {$::myvar ne {}}

When using jdb.tcl for automated tests, breakconditions are preferable to a combination of break points and repeated stepping. Otherwise, whenever the JimTcl script is altered, tests may become out of sync.

Conventions can be used to facilitate testing. To simplify capturing specific output (ignoring the rest) testing.tcl captures any debug output surrounded by XML tags <dbg> and </dbg>. Jdb.tcl has a convenience command pd expr which will print the value of expr surrounded by <dbg> tags. Importantly, expr must contain no line breaks (i.e. it must be on a single line, however long), otherwise jdb.tcl will likely malfunction.

When used with the testing.tcl helper script (which sources JimTcl tcltest.tcl), the debugger can be used for unit and/or integration tests. Nearly any part of a JimTcl script can be instrumented live or in tests, in virtually any script context.

About

Another JimTcl debugger

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages