HELP DEBUG John Williams, July 1987 This file overviews special tools, functions, and macros that may help in debugging Poplog Common Lisp programs. CONTENTS - (Use g to access required sections) 1 Debugging Tools 2 Error Checking Macros 2.1 Poplog-specific variables *test-form* and *test-value* 2.2 Check-type example 2.3 Assert example ----------------------------------------------------------------------- 1 Debugging Tools ----------------------------------------------------------------------- An important element of debugging is finding out what a program is doing at the point it goes wrong. The following utilities may assist in this: trace break inspect The PROFILE module trace is a macro that modifies functions so that they display their arguments and results each time they are executed. The function break invokes the Lisp Debugger. This starts up a new Lisp top-level loop which in addition to evaluating Lisp expressions in the usual way, allows you to examine the function call stack and inspect individual function-call stack frames. inspect is a simple structure browsing tool, enabling interactive investigation and modification of complex data-structures. The PROFILE module provides facilities for profiling execution of Poplog Common Lisp code. Profiling means finding out which functions are the most time-consuming. See the following files for further information: HELP * TRACE HELP * BREAK HELP * INSPECT HELP * PROFILE ----------------------------------------------------------------------- 2 Error Checking Macros ----------------------------------------------------------------------- Another way to facilitate debugging is to use the special error-checking macros provided by Common Lisp. These are: (check-type place type [string]) (assert test-form [({place}*) [datum {argument}*]]) (ccase keyplace {({({key}*) | key} {form}*)}*) (ctypecase keyplace {(type {form}*)}*) (ecase keyform {({({key}*) | key} {form}*)}*) (etypecase keyform {(type {form}*)}*) ccase and ctypecase are similar to case and typecase respectively, except that they signal continuable errors if no key or type is matched. ecase and etypecase are, again, similar to case and typecase, but they signal fatal errors if no key or type is matched. check-type signals a continuable error if place is not of the specified type, and then returns nil. assert signals a continuable error if test-form is nil. (These macros are described in more detail in REF * ERRORS). 2.1 Poplog-specific variables *test-form* and *test-value* ----------------------------------------------------------- The macros listed above all arrange that the form being tested is accessible via the special variable *test-form*, and that the value of this form is accessible via the special variable *test-value*. If an error does occur, continuing (where possible) from the break point that follows the error will enable the user to setf a new value into *test-form*. If the new value is still invalid, the error will be re-signaled. Please note that these special variables are intended for inspection only. Explicitly changing their values during a break-point will probably not affect the behaviour of the program in the desired way. 2.2 Check-type example ----------------------- (setq l '(a b c d e)) (A B C D E) (check-type (car l) number) ;;; MISHAP - Number needed ;;; INVOLVING: A ;;; FILE : /rsuna/home/johnw/cond/debug ;;; LINE : 87 ;;; DOING : (CHECK-TYPE (CAR L) NUMBER) Break: (Error) :H Help :C 1 Supply a new value for (CAR L) <0> :c 1 ;;; Supply a new value for (CAR L) New value: 3 NIL l (3 B C D E) 2.3 Assert example ------------------- The assert macro provides a mechanism for signaling continuable errors when a particular expression evaluates to nil. A list of `places' whose value might need to be changed during debugging can be included in the assert form. This list is accessible during a break via the special variable *assert-places*. In this example, we use assert to check that a number is within two bounds. (defvar *min* 0) *MIN* (defvar *max* 10) *MAX* (setq l '(11 12 13 14 15)) (11 12 13 14 15) (assert (< *min* (car l) *max*) ; test form ((car l)) ; list of places "Value ~D not in the range ~D to ~D" ; error message (car l) *min* *max*) ; error args ;;; MISHAP - Value 11 not in the range 0 to 10 ;;; FILE : /rsuna/home/johnw/cond/debug ;;; LINE : 136 ;;; DOING : (ASSERT (< *MIN* (CAR L) ...) ((CAR L)) ...) Break: (Error) :H Help :C You will be prompted for new values :C 1 Supply a new value for (CAR L) <0> :c 1 ;;; Supply a new value for (CAR L) New value: 9 NIL l (9 12 13 14 15) --- C.all/lisp/help/debug --- Copyright University of Sussex 1987. All rights reserved.