|
From: Michel T. <ta...@lp...> - 2022-02-16 21:06:15
|
Hello,
having been in close contact with the debugger yesterday, i would like
to share some remarks,
which may be useful for newcomers.
First on Maxima 5.43.2 using Lisp SBCL 2.0.1.debian, the command to set
breakpoints doesn't work.
Using the file "example.mac" which contains
kill(all)$
i:3$ j:-2$
bug(i,j):=float(i)/float(j)$
for k from 1 thru 4 do (
i:i+1,
j:j+1,
bug(i,j));
(%i27) :br bug
No line info for $BUG
I had this problem repeatedly with colnew.mac. The only way to set a
breakpoint on a function
is to use trace(bug) with a trace_option. I then devised a method which
is not documented as
far as i have seen, which is to introduce a "function break" in the
source code, like this:
bug(i,j):= (
break(),
float(i)/float(j))$
.................
(%i4) for k from 1 thru 4 do (
i:i+1,
j:j+1,
bug(i,j));
Entering a Maxima break point. Type 'exit;' to resume.
Here one can examine all the variables and see the cause of the bug.
_i;
4
_j;
- 1
_exit; Here the for loop runs once
Entering a Maxima break point. Type 'exit;' to resume.
_i;
5
_j;
0
_exit; Here float(i)/float(j) runs and bugs
Maxima encountered a Lisp error:
arithmetic error DIVISION-BY-ZERO signalled .....
Since we are in a lisp error one can enter the lisp debugger:
(%i5) :lisp(setq *debugger-hook* nil)
....
debugger invoked on a DIVISION-BY-ZERO in thread
#<THREAD "main thread" RUNNING {1000560083}>:
arithmetic error DIVISION-BY-ZERO signalled
Operation was (/ 5.0d0 0.0d0).
restarts (invokable by number or by possibly-abbreviated name):
0: [MACSYMA-QUIT] Maxima top-level
1: [ABORT ] Exit debugger, returning to top level.
(SB-KERNEL:TWO-ARG-/ 5.0d0 0.0d0)
0] ba 5
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1000560083}>
0: (SB-KERNEL:TWO-ARG-/ 5.0d0 0.0d0)
1: (MLAMBDA ((LAMBDA) ((MLIST) $I $J) ((MQUOTIENT) (($FLOAT) $I)
(($FLOAT) $J))) (5 0) $BUG NIL (($BUG) $I $J))
2: (MEVAL1 (($BUG) $I $J))
3: (MEVAL (($BUG) $I $J))
4: (MEVALN ((#1=(MSETQ) $I (#2=(MPLUS) $I 1)) (#1# $J (#2# $J 1))
(($BUG) $I $J)))
The problematic instruction is obvious in frame 1.
One should now hit 0 to return to maxima, but suppose i made an error
and hit 1. All is not lost:
0] 1
* (run)
Maxima restarted.
(%i5)
Now let us modify the program to produce maxima error and not a lisp
error in order to look
at the maxima debugger. So let us modify bug(i,j) to
bug(i,j):= i/j$
and set debugmode(true).
(%i4) for k from 1 thru 4 do (
i:i+1,
j:j+1,
bug(i,j));
expt: undefined: 0 to a negative exponent.
-- an error. Entering the Maxima debugger.
Enter ':h' for help.
bug(i=5,j=0)
(dbm:1)
The first thing to note is that :br still doesn't work.
(%i6) :br bug
Turning on debugging debugmode(true)No line info for $BUG
Consequently :step :next etc. don't work either. What works is:
(dbm:1) :bt
#0: bug(i=5,j=0)
(dbm:1) i;
5
(dbm:1) j;
0
(dbm:1) bug(i,j);
expt: undefined: 0 to a negative exponent.
-- an error. Entering the Maxima debugger.
Enter ':h' for help.
bug(i=5,j=0)
(dbm:2) Second level in the debugger, etc.
So one can examine the variables and run the program by hand in the
context in which the debugger
was called, which is sufficient to do the job. One can even enter the
lisp debugger by issuing:
(dbm:2) :lisp(break)
debugger invoked on a SIMPLE-CONDITION in thread
#<THREAD "main thread" RUNNING {1000560083}>:
break
................
I have tried the same wih clisp, apparently :br runs somewhat better.
In conclusion i think it would be nice to update the manual (section
debugging) with what really
works, at present, notably with sbcl which is the dominant lisp
underlying maxima, and it would also
be useful to indicate there is a function break() in maxima, which
allows to do almost everything useful for
debugging, similar to the function (break) in lisp.
--
Michel Talon
|