The Debugger and Inspector - PowerPoint PPT Presentation

About This Presentation
Title:

The Debugger and Inspector

Description:

Supplying a value for C is the most useful notice we can supply C a one-time ... backtrace of interesting frames limited to m calls if we supply m (:bq 5) ... – PowerPoint PPT presentation

Number of Views:22
Avg rating:3.0/5.0
Slides: 19
Provided by: NKU
Learn more at: https://www.nku.edu
Category:

less

Transcript and Presenter's Notes

Title: The Debugger and Inspector


1
The Debugger and Inspector
  • Two very useful tools available in Common Lisp
    are the debugger and inspector
  • Using them is partially implementation dependent,
    so we will examine these as seen in LispWorks
  • we will also briefly look at two other useful
    tools, step and trace
  • The debugger is entered whenever an error arises
    when executing or compiling code, or if a program
    calls one of the functions error, cerror or break
  • You can also enter the debugger any time you want
    in LispWorks by typing ltcntlgtltbreakgt
  • The debugger provides for you two important
    pieces of information
  • The error message
  • A stack backtrace so that you can see what
    functions were active when the error arose
  • The debugger provides for you a list of options
    that you can select between to proceed
  • This list is partially based on the error itself
    as we will see

2
Cause 1 Arithmetic Error
  • Consider doing (/ 3 0), you will be dropped into
    the debugger with the following options
  • The first choice allows you to abort the function
    but have it return a value
  • this is more useful if the function was being
    called from inside another function so that we
    can proceed from this point by supplying a return
    value
  • The second choice allows you to replace the 0 in
    the denominator
  • this allows you to proceed as if the error did
    not arise by replacing the erroneous value with
    something else
  • You can return to the top level, either by
    aborting (in which case everything is reset) or
    not aborting (any values changed prior to the
    error remain changed)

Error Division-by-zero caused by / of (3 0). 1
(continue) Return a value to use. 2 Supply new
arguments to use. 3 (abort) Return to level 0.
4 Return to top loop level 0.
3
Cause 2 Unknown Identifier
CL-USER 123 gt ( c 5) Error The variable C is
unbound. 1 (continue) Try evaluating C again.
2 Return the value of C instead. 3 Specify a
value to use this time instead of evaluating C.
4 Specify a value to set C to. 5 (abort) Return
to level 0. 6 Return to top loop level 0.
  • The reason for the first response is that it is
    possible that C will gain a value from elsewhere
  • Say if we had multiple processes running
  • Using C allows us to change an unbound variable
    for the value C, but unfortunately it will lead
    to another error because we cannot add a
    non-number
  • Supplying a value for C is the most useful
    notice we can supply C a one-time value (3) or a
    permanent value (4)

4
Examining the Stack
  • One of the commands that you can always try is to
    evaluate the run-time stack
  • In LispWorks, do b at the debugger prompt
  • bb gives you a reduced (brief) backtrack and bq
    gives you an even shorter backtrace
  • This will list all of the function calls leading
    up to the error
  • Notice aside from the programs functions, we
    also have various OS function calls which mostly
    we wont need to know about

From the GA code, I placed a break in
computefitness You can see that evolve called
selectvectors which called computefitnesses The
rest of the calls are from the CL environment OS
Interpreted call to COMPUTEFITNESSES Interpreted
call to SELECTVECTORS Interpreted call to
EVOLVE Call to SPECIALEVAL-NOHOOK Call to
IVPROCESS-TOP-LEVEL Call to CAPICAPI-TOP-LEVEL-
FUNCTION Call to CAPIINTERACTIVE-PANE-TOP-LOOP C
all to (SUBFUNCTION MPPROCESS-SG-FUNCTION
MPINITIALIZE-PROCESS-STACK)
5
Example
(defun weirdfact (n) (if (lt n 0) (break)
(if ( n 0) 1 ( n 2 (weirdfact (- n 2))))))
We will only reach the break if weirdfact
is called with an odd numbered parameter
  • To the right is the backtrace provided
  • ignoring the calls prior to the intepreted call,
    we can see that weirdfact was invoked 4 times (n
    5, n 3, n 1, n -1)
  • we can therefore see when we ran into problems
  • we can also inspect the stack values (as we will
    see shortly)
  • If I resume execution, we enter an infinite loop
  • however I could first alter n (say to be even)
    before resuming to avoid the infinite loop

Calling (weirdfact 5) leads to a break with
the following backtrace Interpreted call to
WEIRDFACT Interpreted call to WEIRDFACT Interprete
d call to WEIRDFACT Interpreted call to
WEIRDFACT Call to SPECIALEVAL-NOHOOK Call to
IVPROCESS-TOP-LEVEL Call to CAPICAPI-TOP-LEVEL-
FUNCTION Call to CAPIINTERACTIVE-PANE-TOP-LOOP C
all to (SUBFUNCTION MP PROCESS-SG-FUNCTION
MPINITIALIZE-PROCESS-STACK)
6
Some Debugger Commands
  • v Print the current frame
  • bq Print quick backtrace of interesting
    frames limited to m calls if we supply m (bq 5)
  • b Print backtrace from the current frame
  • error Print the error and how to continue
  • n Go down the stack by 1 (n m goes down
    by m)
  • p Go up the stack (p m goes up by m)
  • top Abort to top level
  • a Abort one level
  • c Continue from error
  • ret Return from frame
  • res Restart frame
  • sres Restart frame, stepping the function
  • lt Go to the top of the stack
  • gt Go to the bottom of the stack
  • cc Get the current condition object
  • l Print/return value of given variable in
    current frame.
  • show Print all objects found in stack frame
  • grab Grab all objects from a stack frame
  • bb Print a full backtrace suitable for a
    bug report
  • lambda Show lambda expression for frame
  • get ltvariablegt ltcommand identifiergt Get a
    command from the history list and put it in a
    variable.
  • help Produce help list.
  • his optional ltn1gt ltn2gt List command history.
  • redo optional ltcommand identifiergt Redo a
    previous command, identified by its number or a
    substring.
  • use ltnew formgt ltold formgt optional ltcommand
    identifiergt Redo command after replacing old form
    with new form.

7
Example
  • Consider the following function
  • (defun foo (lis1 lis2) (let (temp) (dolist (a
    (append lis1 lis2)) (if (atom a) (setf temp
    (append temp (list a))))) temp))
  • Called by (foo (a b c) d)
  • since d is not a list, append in dolist gives us
    an error and drops us in the debugger with the
    message
  • Error D is not of type LIST.
  • 1 (abort) Return to level 0.
  • 2 Return to top loop level 0.
  • entering b gives us the stack trace
  • Interpreted call to FOO
  • Call to SPECIALEVAL-NOHOOK
  • Call to IVPROCESS-TOP-LEVEL
  • Call to CAPICAPI-TOP-LEVEL-FUNCTION
  • Call to CAPIINTERACTIVE-PANE-TOP-LOOP
  • Call to (SUBFUNCTION MPPROCESS-SG-FUNCTION
    MPINITIALIZE-PROCESS-STACK)
  • not very helpful!

8
Example Continued
  • If we do v we get back the active values on the
    stack
  • Interpreted call to FOO
  • LIS1 (A B C)
  • LIS2 D
  • TEMP (A B C)
  • A C
  • And we can see how these are used if we either do
    (pprint foo) or lambda
  • .'(LAMBDA (LIS1 LIS2)
  • (DECLARE (LAMBDA-NAME FOO))
  • (BLOCK FOO (LET (TEMP) (DOLIST ) TEMP)))
  • Does this help?
  • notice for (dolist ) we dont get to see
    everything, but we can further inspect the
  • What do we do here? The error arose because lis2
    is not a list
  • do (setf lis2 (D)) and then res (restart the
    current frame)
  • this restarts foo, which can now continue until
    it completes, in this case returning (A B C D)

9
Debugger Activities
  • First, identify the cause of the error
  • Next, move down the stack looking over the
    function calls
  • At each stack frame, you can examine the local
    variables using v, show, or l ltnamegt in some
    combination
  • you can change the value of a local variable or
    parameter using setf
  • if, in moving around, you forget the error or
    continuations, type error
  • lt and gt take you to the top and bottom of stack
    respectively if you need to quickly get to one
    end
  • for instance, if youve moved down several
    frames, get back to the top by lt
  • If you have identified the cause of the error and
    fixed it by altering a value, you can restart
    from the point of error by doing res (but first
    go to the top of the stack)
  • If you are still unsure, move to several stack
    frames prior to the error and do sres (invokes
    the stepping function, which we will examine
    later)
  • If you want to give up, you can abort top or
    abort 1 level a or use the continuation that
    takes you to the top level

10
Inspecting the Stack
  • CL has a built in inspector which allows you to
    inspect any stack object
  • describe is a text-based function to inspect an
    object
  • this lists the object, and its component parts if
    it is a sequence, structure or object
  • inspect does the same thing but is interactive
  • this does the same as describe but drops you into
    the interactive inspector
  • the interactive inspector is much like the
    debugger, you can inspect what is going on in the
    object just as you inspect what is going on in
    the stack with the debugger
  • once in the inspector, you can examine any
    individual component, or change components
  • for instance, if the object is a list, you can
    examine each list element, or change any list
    element

11
Inspector Commands
  • d Display current object.
  • dm Display more of current object (if you
    cant see the entire object at one time)
  • sh Show inspector stack.
  • u Undo last inspection.
  • ud Undo last inspection and redisplay.
  • q Quit from current inspector.
  • s s n v sets slot n to value v.
  • i Recursively invoke a new inspector.
  • m Display possible modes or change mode.
  • cv Current values of control variables
    within inspector.
  • h Help on inspector commands.
  • get ltvariablegt ltcommand identifiergt
    Get a command from the history list and put it in
    a variable.
  • help Produce this list.
  • his optional ltn1gt ltn2gt List the
    command history, optionally the last n1 or range
    n1 to n2.
  • redo optional ltcommand identifiergt
    Redo a previous command, identified by its
    number or a substring.
  • use ltnew formgt ltold formgt optional ltcommand
    identifiergt Redo command after
    replacing old form with new form.

12
Example
  • (setf a '(1 2 a "abc" (z y x) (9 8 77 66 55)))

(inspect a) (1 2 A "abc" (Z Y X) ...) is a
LIST 0 1 1 2 2 A 3 "abc" 4
(Z Y X) 5 (9 8 77 66 55) Inspect 1 gt
3 "abc" is a SIMPLE-BASE-STRING 0 \a 1
\b 2 \c Inspect 2 gt u Inspect 1 gt 4
  • (describe a)
  • (1 2 A "abc" (Z Y X) (9 8 77 66 55)) is a LIST
  • 0 1
  • 1 2
  • 2 A
  • 3 "abc"
  • 4 (Z Y X)
  • (9 8 77 66 55)

Selecting 3 recursively inspects it and we are
moved into a lower level of the inspector u
returns us to the previous level Selecting 4
will inspect (Z Y X)
13
Changing Values
  • The s command allows us to change the value of a
    component of the inspected object
  • s 2 b changes a to become (1 2 B "abc" (Z Y X)
    (9 8 77 66 55)))
  • s 3 c changes a to become (1 2 B C (Z Y X) (9
    8 77 66 55)))
  • We can change any value we want, even one of the
    vectors
  • from inspect 1 gt 4 to inspect item 4
  • now we are inspecting the vector (Z Y X)
  • s 2 q ? a is now (1 2 B C (Z Y Q) (9 8 77 66
    55))
  • The inspector can be invoked from inside of the
    debugger so this makes it easy to check out the
    value of variables and make changes to them
    before resuming your function (if desired)
  • inspecting sequences, structures and objects is
    far more useful than inspecting simpler types

S(PERSON NAME FRED SEX M AGE 31 OCCUPATION
NONE) is a PERSON NAME FRED SEX
M AGE 31 OCCUPATION
NONE
Inspecting a structure of type Person we can
reset a value using s age 32 or s occupation
plumber
14
Stepping Through Code
  • The Stepper is a tool that lets you step through
    code
  • In LispWorks, there is a graphical stepper tool
    (click on the boot-shaped icon, or select Stepper
    from the Tools menu)
  • I havent been very successful in using this, so
    instead
  • The stepper is also available at the command
    prompt, just like the debugger and inspector
  • type (step (functioncall params))
  • this brings you into the stepper where you can
    step through the execution of the function
  • s steps down one level of the current function,
    or steps through the next function
  • for instance, (let ((a (/ x 2))) ? s first steps
    into let, then steps into the assignment of a,
    then steps into the divide, then returns to the
    assignment of a
  • st steps through the current function without
    stepping through its specific subparts

15
Stepper Example
(defun bar (a b) (cond ((lt a b) (- a b)) (t ( a
b)))) (step (bar 3 5)) (BAR 3 5) -gt s 3 -gt
s 3 5 -gt s 5 (DECLARE
(SPECIALSOURCE (LAMBDA (A B) (DECLARE
(LAMBDA-NAME BAR)) (BLOCK BAR (COND ((lt A B)
(- A B)) (T ( A B)))))) (LAMBDA-NAME BAR)) -gt
s NIL (BLOCK BAR (COND ((lt A B) (- A B))
(T ( A B)))) -gt s (COND ((lt A B) (- A B))
(T ( A B))) ltgt (IF (lt A B) (PROGN (- A
B)) (COND (T ( A B))))
16
Step Example Continued
(IF (lt A B) (PROGN (- A B)) (COND (T ( A B))))
-gt s (lt A B) -gt s A -gt s
3 B -gt s 5
T (PROGN (- A B)) -gt s (-
A B) -gt s A -gt s
3 B -gt s 5
-2 -2 -2 -2 -2 -2
By using si, we can skip a lot of the details
17
Stepper Commands
  • s Step this form and all of its subforms
    (optional ve integer arg)
  • st Step this form without stepping its
    subforms
  • si Step this form without stepping its
    arguments if function call
  • su Step up out of this form without
    stepping its subforms
  • sr Return a value to use for this form
  • sq Quit from the current stepper level
  • get ltvariablegt ltcommand identifiergt
    Get a command from the history list and put it in
    a variable.
  • help Produce this list.
  • his optional ltn1gt ltn2gt List the
    command history, optionally the last n1 or range
    n1 to n2.
  • redo optional ltcommand identifiergt
    Redo a previous command, identified by its number
    or a substring.
  • use ltnew formgt ltold formgt optional ltcommand
    identifiergt Redo command after
    replacing old form with new form.

18
Trace Facility
  • Trace allows you to trace function calls
  • (trace functionname) turns trace on
  • Next time you call functionname, you get to see
    its behavior what it calls, what the parameters
    are
  • (untrace functionname) turns trace off

here, fib (the fibonacci function), is called
with (fib 4) 0 FIB gt ... gtgt N 4 1 FIB gt
... gtgt N 3 2 FIB gt ... gtgt N 2
2 FIB lt ... ltlt VALUE-0 1 2 FIB gt
... gtgt N 1 2 FIB lt ... ltlt
VALUE-0 1
1 FIB lt ... ltlt VALUE-0 2 1 FIB gt ...
gtgt N 2 1 FIB lt ... ltlt VALUE-0 1 0 FIB lt
... ltlt VALUE-0 3 3
for more on these facilities, see the LispWorks
web site
Write a Comment
User Comments (0)
About PowerShow.com