README file for TDebug, an alternative tcl/tk-debugger. $Id: README,v 3.1 1993/12/06 01:39:09 schmid Exp schmid $ This file documents TDebug Verion 0.3. It was written with emacs using Jamie Lokier's folding mode That's what the funny {{{ marks are there for. Please send comments, suggestions, bug-reports etc to schmid@fb3-s7.math.tu-berlin.de Any feedback is welcome! {{{ Disclaimer This code is still under development. Among other things this means that: This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. There is still a long way to go to make this a useful debugger, but the start is here. }}} {{{ Files README this file TdChoose.tcl the TDebug front end TdDebug.tcl the debugger }}} {{{ General TDebug uses a different approach than any other debugger I've seen for tcl/tk. If you know the emacs-lisp debugger `edebug' the following may seem familiar. TDebug is totally based on tcl/tk, there is no C-code (yet), 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 TDebug 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. On the downside there is a heavy penalty on speed and flexibility. I would like to include some optional low-level tracing, but I have no idea how to get the information about the point of execution relative to the current proc from inside the trace routines. Help on this would be appreciated! I have also tried Don Libes' debugger provided with expect (and standalone) and Karl Lehenbauer's experimental debugger that comes with extended tcl (tclX). Both of them are far more powerful than TDebug though Karl's is far from using its full potential. On the other hand, neither is as easy to install as TDebug, and neither comes with a graphical interface. If you have to debug large applications or huge procs or need to have control over code not inside of a proc, you are probably best off using Don's debugger (which is the one I use to debug TDebug :-), but for a first quick look inside a simple proc TDebug may become your debugger of choice. }}} {{{ Installation IMPORTANT: Look at the file TdChoose.tcl. Near the top there is a place where you have to set one variable to the full pathname of the directory you have placed TdDebug.tcl into. As an alternative you can put TdDebug.tcl somwhere in your standard tcl/tk auto_path and make sure that tclIndex is updated correctly. There are really two versions of TDebug, but contained in one source. Under normal circumstances, TdChoose.tcl, the TDebug frontend, provides a standalone application that talks to other tcl/tk-based apps via send. To debug a running application, TDebug sends a `source TdDebug.tcl' to it, making the debugger available. You can then choose procs to prepare for debugging. There are however lots of people for whom send doesn't work. In this case you have to source TdChoose.tcl inside the application you want to debug, BUT DOING `set td_priv(send) 0' FIRST! You can put this into a file called .tdebugrc in your home directory (see Configuration section of README). }}} {{{ Usage The Chooser: Running TdChoose.tcl will bring up a toplevel window that let's you select the application you wish to debug, if it is allready running. If you cannot use send and have installed TdChoose.tcl correctly, the current application will be used instead. The listbox displays all procs available for preparing or restoring from the selected interpreter. To prepare a proc for debugging, click Button-1 once on it's name while the `Prepare' radiobutton is active, to restore it to it's original form, do the same with the `Restore' button active. You can force a rescan of the available procs by pressing the `Prepare' or `Restore' button accordingly. The Debugger: The debugger window is divided into the main region with the name of the current proc, a listing in which the expression just executed is highlighted, the result of this execution and the currently available variables and their values, an entry to eval expressions in the context of the current proc and some controls for the state of the debugger. There are seven possible debugger states, one for each button and an `idle' or `waiting' state when no button is active. The others are: Stop - Stop after next expression, used to get out of slow/fast/nonstop mode. Next - Execute one expression, then revert to idle. Slow - Execute until end of proc, stopping at breakpoints or when the state changes to stop. After each execution, stop for `delay' milliseconds. The delay can be changed with the `+' and `-' buttons. Fast - Execute until end of proc, stopping at breakpoints. Nonstop - Execute until end of proc without stopping at breakpoints or updating the display. Break - Terminate execution of current proc. The menus should be obvious, except that the entries in the `Selection' menu only work in `idle' state. 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. Breakpoints: To set/unset a breakpoint, double-click inside the listing. The breakpoint will be set at the innermost available expression that contains the position of the click. There's no support for conditional or counted breakpoints yet. }}} {{{ Configuration You can customize TDebug by setting up a file named .tdebugrc in your home directory. There isn't much you can configure at the moment, but you can use it to set the following variables: Variable Value Effect ----------------------------------------------------------------------- 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(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(delay) Delay in milliseconds used with slow stepping (100-1500) td_priv(detail) low Don't check for subexpressions when preparing procs high Do check for subexpressions td_priv(constrainscroll) 1 Don't scroll after last line in listing 0 Normal scrolling }}} {{{ Todo As I have said, TDebug is in a very early stage. I hope to implement the following features sometime (I hope soon, depending on feedback): * Make a dialog to display widget information - selectable from hierarchy * When exiting td_Choose restore all procs to their original form. * Better parsing. Switch statements don't work well yet. * Either some interface to low-level debugging or a wrap around the `source' command to get access to code running in global context. * Conditional breakpoints, watchpoints. * Make proc listings available without preparing the proc. Allow partial preparing for speed and efficiency. * Better documentation * Optionally display only selected variables, especially arrays. * WHATEVER good ideas YOU come up with. }}} {{{ Credits Thanks to: John Ousterhout for tcl/tk Allesandro Rubini for numerous good ideas }}} {{{ Emacs local variables Local variables: mode: text folded-file: t End: }}}