The Debugger and Inspector Two very useful tools available in Common Lisp are the debugger and inspector –Using them is partially implementation dependent,

Slides:



Advertisements
Similar presentations
Ruby (on Rails) CSE 190M, Spring 2009 Week 2. Arrays Similar to PHP, Ruby arrays… – Are indexed by zero-based integer values – Store an assortment of.
Advertisements

Some non-recursive tricks. The Lambda expression. More on Let, Let*, apply and funcall.
Debugging What can debuggers do? Run programs Make the program stops on specified places or on specified conditions Give information about current variables’
Introduction to Computing Science and Programming I
A problem with functions: arguments must always have values that can be worked out Whenever we call a function we give it arguments. Lisp then works out.
Programming with Alice Computing Institute for K-12 Teachers Summer 2011 Workshop.
Lisp Recitation (cse471/598 Fall 2007 ) Aravind Kalavagattu.
Lists Introduction to Computing Science and Programming I.
Six compound procedures and higher-order procedures.
Lisp. Versions of LISP Lisp is an old language with many variants –LISP is an acronym for List Processing language Lisp is alive and well today Most modern.
The IDE (Integrated Development Environment) provides a DEBUGGER for locating and correcting errors in program logic (logic errors not syntax errors) The.
Stacks. 2 What is a stack? A stack is a Last In, First Out (LIFO) data structure Anything added to the stack goes on the “top” of the stack Anything removed.
How to Debug VB .NET Code.
Stacks. 2 What is a stack? A stack is a Last In, First Out (LIFO) data structure Anything added to the stack goes on the “top” of the stack Anything removed.
Computer Science 1620 Programming & Problem Solving.
Functional Programming COMP2003 A course on functional programming using Common Lisp Dr Eleni Mangina
General pattern for selecting some elements of a list This negatives example illustrates a general pattern: If you want a function which selects some elements.
Lisp: An Introduction Lisp – List Processing language
Advanced Functions In CL, functions are often supplied as parameters to other functions –This gives us tremendous flexibility in writing functions whose.
Input/Output Chapters 7 & 9. Output n Print produces output > (print 100) n It also returns the value it printed –that’s where the second 100 came.
The Case primitive: matches the evaluated key form against the unevaluated keys by using eql The general format of case is the following: (case (... ).....
Error Handling Common Lisp has the throw/catch statements so that you can simulate exception handling as seen in languages like Java But CL goes far beyond.
Chapter 13 Recursion. Learning Objectives Recursive void Functions – Tracing recursive calls – Infinite recursion, overflows Recursive Functions that.
Debugging Dwight Deugo Nesa Matic
Debugging. 2 © 2003, Espirity Inc. Module Road Map 1.Eclipse Debugging  Debug Perspective  Debug Session  Breakpoint  Debug Views  Breakpoint Types.
Debugging in Java. Common Bugs Compilation or syntactical errors are the first that you will encounter and the easiest to debug They are usually the result.
CPS120: Introduction to Computer Science Decision Making in Programs.
Presented by IBM developer Works ibm.com/developerworks/ 2006 January – April © 2006 IBM Corporation. Making the most of The Eclipse debugger.
The Loop Macro Many of the CL “functions” are actually macros (let, progn, if, etc) The most complicated macro in CL is probably the Loop macro –The Loop.
Making Python Pretty!. How to Use This Presentation… Download a copy of this presentation to your ‘Computing’ folder. Follow the code examples, and put.
Allegro CL Certification Program Lisp Programming Series Level I Session Basic Lisp Development in the IDE.
+ Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy Walters, and Godfrey Muganda Chapter 5: Looping.
Perl Tutorial. Why PERL ??? Practical extraction and report language Similar to shell script but lot easier and more powerful Easy availablity All details.
UMBC CMSC Common Lisp II. UMBC CMSC Input and Output Print is the most primitive output function > (print (list 'foo 'bar)) (FOO BAR) The.
1 Debugging and Syntax Errors in C++. 2 Debugging – a process of finding and fixing bugs (errors or mistakes) in a computer program.
PRACTICAL COMMON LISP Peter Seibel 1.
Scripting Languages Diana Trandab ă ț Master in Computational Linguistics - 1 st year
©Ian Sommerville 2004Software Engineering, 7th edition. Chapter 4 Slide 1 Slide 1 What we'll cover here l Using the debugger: Starting the debugger Setting.
Milos Hauskrecht (PDF) Hieu D. Vu (PPT) LISP PROGARMMING LANGUAGE.
Georgia Institute of Technology Creating Classes part 2 Barb Ericson Georgia Institute of Technology June 2006.
Exceptions and Assertions Chapter 15 – CSCI 1302.
Introduction to LISP Atoms, Lists Math. LISP n LISt Processing n Function model –Program = function definition –Give arguments –Returns values n Mathematical.
Chapter 5 Methods 1. Motivations Method : groups statements that perform a function.  Level of abstraction (black box)  Code Reuse – no need to reinvent.
M1G Introduction to Programming 2 2. Creating Classes: Game and Player.
LECTURE 2 Python Basics. MODULES So, we just put together our first real Python program. Let’s say we store this program in a file called fib.py. We have.
Debugging using By: Samuel Ashby. What is debugging?  A bug is an error in either a program or the hardware itself.  Debugging is first locating and.
Dale Roberts Debugger Dale Roberts, Lecturer Computer Science, IUPUI Department of Computer and Information Science, School.
1 Outline Review Introduction to LISP Symbols and Numbers Lists Writing LISP Functions LISPWorks.
Artificial Intelligence and Lisp Lecture 6 LiU Course TDDC65 Autumn Semester,
Winter 2009 Tutorial #6 Arrays Part 2, Structures, Debugger
User-Written Functions
Section 15.4, 15.6 plus other materials
Debugging Dwight Deugo
Why exception handling in C++?
Getting Started with Lisp
Barb Ericson Georgia Institute of Technology Dec 2009
Important terms Black-box testing White-box testing Regression testing
Sentinel logic, flags, break Taken from notes by Dr. Neil Moore
Important terms Black-box testing White-box testing Regression testing
Debugging Taken from notes by Dr. Neil Moore
RECURSION Haskell.
6.001 SICP Variations on a Scheme
Debugging Taken from notes by Dr. Neil Moore
Peter Seibel Practical Common Lisp Peter Seibel
Debugging Dwight Deugo
Common Lisp II.
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
Lisp.
Good programming practices
The general format of case is the following: (case <key form>
Presentation transcript:

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 + –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

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.

Cause 2: Unknown Identifier 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) CL-USER 123 > (+ 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.

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 program’s functions, we also have various OS function calls which mostly we won’t need to know about Interpreted call to COMPUTEFITNESSES Interpreted call to SELECTVECTORS Interpreted call to EVOLVE Call to SPECIAL::%EVAL-NOHOOK Call to IV:PROCESS-TOP-LEVEL Call to CAPI::CAPI-TOP-LEVEL-FUNCTION Call to CAPI::INTERACTIVE-PANE-TOP-LOOP Call to (SUBFUNCTION MP::PROCESS-SG-FUNCTION MP::INITIALIZE-PROCESS-STACK) 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

Example 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 (defun weirdfact (n) (if (< 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 Calling (weirdfact 5) leads to a break with the following backtrace: Interpreted call to WEIRDFACT Call to SPECIAL::%EVAL-NOHOOK Call to IV:PROCESS-TOP-LEVEL Call to CAPI::CAPI-TOP-LEVEL-FUNCTION Call to CAPI::INTERACTIVE-PANE-TOP-LOOP Call to (SUBFUNCTION MP:: PROCESS-SG-FUNCTION MP::INITIALIZE-PROCESS-STACK)

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 :< Go to the top of the stack :> 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 Get a command from the history list and put it in a variable. :help Produce help list. :his &optional List command history. :redo &optional Redo a previous command, identified by its number or a substring. :use &optional Redo command after replacing old form with new form.

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 SPECIAL::%EVAL-NOHOOK Call to IV:PROCESS-TOP-LEVEL Call to CAPI::CAPI-TOP-LEVEL-FUNCTION Call to CAPI::INTERACTIVE-PANE-TOP-LOOP Call to (SUBFUNCTION MP::PROCESS-SG-FUNCTION MP::INITIALIZE- PROCESS-STACK) –not very helpful!

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 don’t 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)

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 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 –: take you to the top and bottom of stack respectively if you need to quickly get to one end for instance, if you’ve moved down several frames, get back to the top by :< 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

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

Inspector Commands :d Display current object. :dm Display more of current object (if you can’t 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 Get a command from the history list and put it in a variable. :help Produce this list. :his &optional List the command history, optionally the last n1 or range n1 to n2. :redo &optional Redo a previous command, identified by its number or a substring. :use &optional Redo command after replacing old form with new form.

Example (setf a '(1 2 a "abc" #(z y x) #( ))) (describe a) (1 2 A "abc" #(Z Y X) #( )) is a LIST A 3 "abc" 4 #(Z Y X) 5#( ) (inspect a) (1 2 A "abc" #(Z Y X)...) is a LIST A 3 "abc" 4 #(Z Y X) 5 #( ) Inspect 1 > 3 "abc" is a SIMPLE-BASE-STRING 0 #\a 1 #\b 2 #\c Inspect 2 > :u Inspect 1 > 4 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)

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) #( ))) –:s 3 ’c changes a to become (1 2 B C #(Z Y X) #( ))) We can change any value we want, even one of the vectors –from inspect 1 > 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) #( )) 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

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 haven’t 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

Stepper Example (defun bar (a b) (cond ((< a b) (- a b)) (t (+ a b)))) (step (bar 3 5)) (BAR 3 5) -> :s 3 -> :s 3 5 -> :s 5 (DECLARE (SPECIAL:SOURCE (LAMBDA (A B) (DECLARE (LAMBDA-NAME BAR)) (BLOCK BAR (COND ((< A B) (- A B)) (T (+ A B)))))) (LAMBDA-NAME BAR)) -> :s NIL (BLOCK BAR (COND (( :s (COND (( (IF (< #:A #:B) (PROGN (- #:A #:B)) (COND (T (+ #:A #:B))))

Step Example Continued (IF ( :s ( :s A -> :s 3 B -> :s 5 T (PROGN (- A B)) -> :s (- A B) -> :s A -> :s 3 B -> :s 5 -2 By using :si, we can skip a lot of the details

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 Get a command from the history list and put it in a variable. :help Produce this list. :his &optional List the command history, optionally the last n1 or range n1 to n2. :redo &optional Redo a previous command, identified by its number or a substring. :use &optional Redo command after replacing old form with new form.

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 >... >> N : 4 1 FIB >... >> N : 3 2 FIB >... >> N : 2 2 FIB <... << VALUE-0 : 1 2 FIB >... >> N : 1 2 FIB <... << VALUE-0 : 1 1 FIB <... << VALUE-0 : 2 1 FIB >... >> N : 2 1 FIB <... << VALUE-0 : 1 0 FIB <... << VALUE-0 : 3 3 for more on these facilities, see the LispWorks web site