For bug reports or patches, please consult the Tixapps User's Forum.
Copyright (C) 1993 Gregor Schmid
This software is copyrighted by Gregor Schmid. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files.
The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
TixDebug is solely based on Tcl/Tk, there is no C-code, which makes it very easy to install. It works by parsing and redefining Tcl/Tk-procs, inserting calls to `td_eval' at certain points, which takes care of the display, stepping, breakpoints, variables etc.
The advantages are that TixDebug knows which statement in what proc is currently being executed and can give visual feedback by highlighting it. All currently accessible variables and their values are displayed as well. Code can be evaluated in the context of the current proc. Breakpoints can be set and deleted with the mouse.
Unfortunately there are back-draws to this approach. Preparation of large procs is slow and due to Tcl's dynamic nature there is no guarantee, that a proc can be prepared at all.
This problem has been alleviated somewhat with the introduction of partial preparation of procs. There is still no possibility to get at code running in global context, but I'm not sure if that would be useful anyway.
There are really two versions of TixDebug, but contained in one source.
Under normal circumstances, TixdChoose.tcl, the TixDebug frontend, provides a standalone application that talks to other Tcl/Tk-based applications via `send'. To debug a running application, TixDebug sends a `source TixdDebug.tcl' to it, making the debugger available. You can then choose procs to prepare for debugging.
Depending on your installation the Tk command `send' may not work for
you. In this case you should create a configuration file called
.tixdebugrc
in your home directory that contains the line
~/.tixdebugrc
file.
tixwish Tixapps.tcl tixdebugIf you can use `send', this will bring up the Chooser which lets you switch between all running Tk applications.
Caveat: Due to incompatibilities in the `send' command of Tk versions, you may only be able debug applications running with an interpreter of the same generation as the Debugger. TixDebug cannot detect whether another interpreter is compatible or not until it tries to send a command to it.
If you can't use `send', give the program you wish to debug as argument on the command line, e.g.
tixwish TixdChoose.tcl test.tclThis will start your application and the debugger in the same interpreter. Running TixDebug this way will always disable the use of the send command.
At the top the current interpreter is shown. If you are using send you can use the `+' button to pop up a menu and select a different interpreter.
In the main section there are two listboxes. The first one shows all procs that are defined in the current interpreter. By clicking the left mouse button on a proc name, the proc gets prepared for debugging and its name is moved to the second listbox. Clicking a name in the second listbox returns a proc to its normal state.
You can control whether TixDebug specific procs and Tk specific procs are displayed in the listbox or not. See the Configuration section.
Press the right mouse button on a proc in either listbox to get its program code displayed in the main debugger window.
The three buttons at the bottom let you force a rescan of the available procs, pop up the debugger window or exit TixDebug.
Exiting from TixDebug doesn't terminate the running application, it merely detaches from all interpreters, restoring all prepared procs to their unmodified state.
A proc listing displayed in the main region will have a darker background on all lines that have been prepared. You can prepare or restore additional lines by selecting a region (<Button-1>, standard selection) and choosing `Prepare' or `Restore' from the Selection menu (or by pressing ^P or ^R).
`Prepare' and `Restore' try to be smart about what you intend to do. If you select just a single word (plus some optional whitespace) it will be interpreted as the name of a proc to prepare or restore. Otherwise, if the selection is owned by the listing, the corresponding lines will be used.
Be careful with partial prepare or restore! If you prepare random lines inside a `switch' or `bind' expression, you may get surprising results on execution, because the parser doesn't know about the surrounding expression and can't try to prevent problems.
There are seven possible debugger states, one for each button and an `idle' or `waiting' state when no button is active. The others are:
Closing the debugger doesn't quit it, it only does `wm withdraw'. The debugger window will pop up the next time a prepared proc is called.
The `Eval: ' entry supports a simple history mechanism available via the <Up> and <Down> keys. If you evaluate a command while stepping through a proc, the command will be evaluated in the context of the proc, otherwise at global level. The result will be displayed in the result field.
This entry is useful for a lot of things, but especially to get access to variables outside the current scope. Try entering the line `global td_priv' and watch the `Variables' box (with global and array variables enabled of course).
.tixdebugrc
in your home directory.
The following variables have special effects:
Variable | Value |
td_priv(wrap) | none Don't wrap listing of current proc |
word Word-wrap listing | |
td_priv(wrapback) | none Don't wrap backtrace |
word Word-wrap backtrace | |
td_priv(fullnames) | 1 Display full widget names |
0 Display the last part only | |
td_priv(update) | slow Always update variables |
fast Update variables in idle state only | |
td_priv(detail) | low Don't check for subexpressions when preparing procs |
high Do check for subexpressions | |
td_priv(delay) | Delay in milliseconds used with slow stepping (100-1500) |
td_priv(globalvars) | 1 Display global variables accessible from current proc |
0 Don't display global variables | |
td_priv(arrayvars) | 1 Display array variables similar to parray |
0 Don't display arrays (they take too much space) | |
td_priv(scrollbarside) | left Place all scrollbars at the left side |
right Place all scrollbars at the right side | |
td_priv(constrainscroll) | 1 Don't scroll after last line in listing |
0 Normal scrolling | |
td_priv(height) | Height of proc listing |
td_priv(listwidth) | Width of proc listing |
td_priv(varwidth) | Width of variable display |
td_priv(geometry) | Geometry of Debugger window. Use for position only! |
td_priv(preparedtag) | tag style for prepared lines |
td_priv(activetag) | tag style for currently active expression |
td_priv(breaktag) | tag style for breakpoints Tag styles are used for .widget tag configure
...
For example "-background red -foreground blue" etc. |
td_priv(tagpriority) | priority of tags, lowest priority first.
Legal tag values are (default priority): prepared sel active break |
td_priv(foreground) | Coloring of foreround primarily text |
td_priv(background1) | Coloring of primary window background |
td_priv(background2) | Coloring of child frame backgrounds |
td_priv(useblt) | 0 Don't use BLT, even if available |
If unset, use BLT if it is available |
Variable | Value |
td_priv(send) | 0 Can't use send |
1 Can use it | |
td_priv(scrollbarside) | left Place all scrollbars at the left side |
right Place all scrollbars at the right side | |
td_priv(constrainscroll) | 1 Don't scroll after last line in listing |
0 Normal scrolling | |
td_priv(chooseheight) | Height of chooser box |
td_priv(choosewidth) | Width of chooser box |
td_priv(choosegeometry) | Geometry of Choose window.
Use for position only! |
td_priv(hideownprocs) | 1 Don't display procs belonging to TixDebug |
0 Display those procs (be careful!) | |
td_priv(hidetkprocs) | 1 Don't display procs belonging to Tk,
i.e. tk_*, auto_* and unknown. |
0 Display those procs | |
td_priv(debugdir) | Set to the directory containing TixdDebug.tcl.
Not necessary if it is the same as TixdChoose.tcl. |
Variable | Value |
td_priv(backtraceheight) | Height of backtrace |
td_priv(backtracewidth) | Width of backtrace |
td_priv(backtracegeometry) | Geometry of Backtrace window. Use for position only! |
Variable | Value |
td_priv(errorheight) | Height of error trace |
td_priv(errorwidth) | Width of error trace |
td_priv(errorgeometry) | Geometry of ErrorTrace window. Use for position only! |
Variable | Value |
td_priv(widgetsheight) | Height of hierarchy |
td_priv(widgetswidth) | Width of hierarchy |
td_priv(widgetsgeometry) | Geometry of WidgetHierarchy window. Use for position only! |
The following known problems exist:
switch expressions of the type
A multiple line expr without `\' will fail:
If you run into such problems, restore the offending lines via the selection mechanism and try again.