;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*- =Node: 4The Debugger* =Text: 3THE DEBUGGER* When an error condition is signaled and no handlers decide to handle the error, an interactive debugger is entered to allow the user to look around and see what went wrong, and to help him continue the program or abort it. This section describes how to use the debugger. =Node: 4Entering the Debugger* =Text: 3ENTERING THE DEBUGGER* There are two kinds of errors; those generated by the Lisp Machine's microcode, and those generated by Lisp programs (by using 2ferror* or related functions). When there is a microcode error, the debugger prints out a message such as the following: 3>>TRAP 5543 (TRANS-TRAP)* 3The symbol FOOBAR is unbound.* 3While in the function LOSE-XCT  LOSE-COMMAND-LOOP  LOSE* The first line of this error message indicates entry to the debugger and contains some mysterious internal microcode information: the micro program address, the microcode trap name and parameters, and a microcode backtrace. Users can ignore this line in most cases. The second line contains a description of the error in English. The third line indicates where the error happened by printing a very abbreviated ``backtrace'' of the stack (see below); in the example, it is saying that the error was signaled inside the function 2lose-xct*, which was called by 2lose-command-loop*. Here is an example of an error from Lisp code: 3>>ERROR: The argument X was 1, which is not a symbol,* 3While in the function FOO  SI:EVAL1  SI:LISP-TOP-LEVEL1* Here the first line contains the English description of the error message, and the second line contains the abbreviated backtrace. 2foo* signaled the error by calling 2ferror*; however, 2ferror* is censored out of the backtrace. After the debugger's initial message, it prints the function that got the error and its arguments. Then it prints a list of commands you can use to proceed from the error, or to abort to various command loops. The possibilities depend on the kind of error and where it happened, so the list is different each time; that is why the debugger prints it. The commands in the list all start with 2Super-A*, 2Super-B* and continue as far as is necessary. 3eh:*inhibit-debugger-proceed-prompt** 1Variable* If this is non-2nil*, the list of 2Super* commands is not printed when the debugger is entered. Type 2Help P* to see the list. The debugger normally uses the stream 2*debug-io** for all its input and output (see 4(IOSYSTEM-2)Standard Streams*). By default it is a synonym for 2*terminal-io**. The value of this variable in the stack group in which the error was signaled is the one that counts. 3eh:*debug-io-override** 1Variable* If this is non-2nil*, it is used by the debugger instead of the value of 2*debug-io**. The value in the stack group where the error was signaled is the one that counts. The debugger can be manually entered either by causing an error (e.g. by typing a ridiculous symbol name such as 2ahsdgf* at the Lisp read-eval-print loop) or by typing the 2Break* key with the 2Meta* shift held down while the program is reading from the terminal. Typing the 2Break* key with both 2Control* and 2Meta* held down forces the program into the debugger immediately, even if it is running. If the 2Break* key is typed without 2Meta*, it puts you into a read-eval-print loop using the 2break* function (see 4(MISCELL-2)The Lisp Listen Loop*) rather than into the debugger. 3eh* &optional 1process* Causes 1process* to enter the debugger, and directs the debugger to read its commands from the ambient value of 2*terminal-io**, current when you call 2eh*, rather than 1process*'s own value of 2*terminal-io** which is what would be used if 1process* got an error in the usual way. The process in which you invoked 2eh* waits while you are in the debugger, so there is no ambiguity about which process will handle your keyboard input. If 1process* had already signaled an error and was waiting for exposure of a window, then it enters the debugger to handle that error. Otherwise, the 2break* condition is signaled in it (just like what 2Control-Meta-Break* does) to force it into the debugger. The 2Resume* command makes 1process* resume execution. You can also use other debugger commands such as 2Abort*, 2Control-R*, 2Control-Meta-R* and 2Control-T* to start it up again. Exiting the debugger in any way causes 2eh* to return in its process. 1process* can also be a window, or any flavor instance which understands the 2:process* operation and returns a process. If 1process* is not a process but a stack group, the current state of the stack group is examined. In this case, the debugger runs in ``examine-only'' mode, and executes in the process in which you invoked 2eh*. You cannot resume execution of the debugged stack group, but 2Resume* exits the debugger. It is your responsibility to ensure that no one tries to execute in the stack group being debugged while the debugger is looking at it. If 1process* is 2nil*, 2eh* finds all the processes waiting to enter the debugger and asks you which one to use. =Node: 4How to Use the Debugger* =Text: 3HOW TO USE THE DEBUGGER* Once inside the debugger, the user may give a wide variety of commands. This section describes how to give the commands, then explains them in approximate order of usefulness. A summary is provided at the end of the listing. When the debugger is waiting for a command, it prompts with an arrow: 3 * If the error took place in the evaluation of an expression that you typed at the debugger, you are in a second level (or deeper) error. The number of arrows in the prompt indicates the depth. The debugger also warns you about certain unusual circumstances that may cause paradoxical results. For example, if 2default-cons-area* is anything except 2working-storage-area*, a message to that effect is printed. If 2*read-base** and 2*print-base** are not the same, a message is printed. At this point, you may type either a Lisp expression or a command; a 2Control* or 2Meta* character is interpreted as a command, whereas most normal characters are interpreted as the first character of an expression. If you type the 2Help* key or the 2?* key, you can get some introductory help with the debugger. If you type a Lisp expression, it is interpreted as a Lisp form and evaluated in the context of the current frame. That is, all dynamic bindings used for the evaluation are those in effect in the current frame, with certain exceptions explained below. The results of the evaluation are printed, and the debugger prompts again with an arrow. If, during the typing of the form, you change your mind and want to get back to the debugger's command level, type the 2Abort* key or a 2Control-G*; the debugger responds with an arrow prompt. In fact, at any time that input is expected from you, while you are in the debugger, you may type 2Abort* or 2Control-G* to cancel any debugger command that is in progress and get back to command level. 2Control-G* is useful because it can never exit from the debugger as 2Abort* can. This 2read-eval-print* loop maintains the values of 2+*, 2**, and 2-* almost like the Lisp listen loop. The difference is that some single-character debugger commands such as 2C-M-A* also set 2** and 2+* in their own way. If an error occurs in the evaluation of the Lisp expression you type, you may enter a second invocation of the debugger, looking at the new error. The prompt in this event is `3*' to make it clear which level of error you are examining. You can abort the computation and get back to the first debugger level by typing the 2Abort* key (see below). Various debugger commands ask for Lisp objects, such as an object to return or the name of a catch-tag. You must type a form to be evaluated; its value is the object that is actually used. This provides greater generality, since there are objects to which you might want to refer that cannot be typed in (such as arrays). If the form you type is non-trivial (not just a constant form), the debugger shows you the result of the evaluation and asks for confirmation before proceeding. If you answer negatively, or if you abort, the command is canceled and the debugger returns to command level. Once again, the special bindings in effect for evaluation of the form are those of the current frame you have selected. The 2Meta-S* and 2Control-Meta-S* commands allow you to look at the bindings in effect at the current frame. A few variables are rebound by the debugger itself whenever a user-provided form is evaluated, so you you must use 2Meta-S* to find the values they actually had in the erring computation. 2*terminal-io** 2*terminal-io** is rebound to the stream the debugger is using. 2*standard-input** 2*standard-output**standard-input** and 2*standard-output** are rebound to be synonymous with 2*terminal-io**. 2+, ++, +++* 2*, **, ***, *values*+* and 2** are rebound to the debugger's previous form and previous value. Commands for examining arguments and such, including 2C-M-A*, 2C-M-L* and 2C-M-V*, leave 2** set to the value examined and 2+* set to a locative to where the value was found. When the debugger is first entered, 2+* is the last form typed, which is typically the one that caused the error, and 2** is the value of the 1previous* form. 2evalhook* 2applyhook* These variables (see 4(DEBUGGING-6)Evalhook*) are rebound to 2nil*, turning off the 2step* facility if it was in use when the error occurred. 2eh:condition-handlers* 2eh:condition-default-handlers*These are rebound to 2nil*, so that errors occurring within forms you type while in the debugger do not magically resume execution of the erring program. 2eh:condition-resume-handlers* To prevent resume handlers established outside the error from being invoked automatically by deeper levels of error, this variable is rebound to a new value, which has an element 2t* added in the front. =Node: 4Debugger Commands* =Text: 3DEBUGGER COMMANDS* All debugger commands are single characters, usually with the 2Control* or 2Meta* bits. The single most useful command is 2Abort* (or 2Control-Z*), which exits from the debugger and throws out of the computation that got the error. (This is the 2Abort* key, not a 5-letter command.) Often you are not interested in using the debugger at all and just want to get back to Lisp top level; so you can do this in one keystroke. If the error happened while you were innocently using a system utility such as the editor, then it represents a bug in the system. Report the bug using the debugger command 2Control-M*. This gives you an editor preinitialized with the error message and a backtrace. You should type in a 1precise* description of what you did that led up to the problem, then send the message by typing 2End*. Be as complete as possible, and always give the exact commands you typed, exact filenames, etc. rather then general descriptions, as much as possible. The person who investigates the bug report will have to try to make the problem happen again; if he does not know where to find 1your* file, he will have a difficult time. The 2Abort* command signals the 2sys:abort* condition, returning control to the most recent command loop. This can be Lisp top level, a 2break*, or the debugger command loop associated with another error. Typing 2Abort* multiple times throws back to successively older read-eval-print or command loops until top level is reached. Typing 2Meta-Abort*, on the other hand, always throws to top level. 2Meta-Abort* is not a debugger command, but a system command that is always available no matter what program you are in. Note that typing 2Abort* in the middle of typing a form to be evaluated by the debugger aborts that form and returns to the debugger's command level, while typing 2Abort* as a debugger command returns out of the debugger and the erring program, to the 1previous* command level. Typing 2Abort* after entering a numeric argument just discards the argument. Self-documentation is provided by the 2Help* or 2?* command, which types out some documentation on the debugger commands, including any special commands that apply to the particular error currently being handled. Often you want to try to proceed from the error. When the debugger is entered, it prints a table of commands you can use to proceed, or abort to various levels. The commands are 2Super-A*, 2Super-B*, and so on. How many there are and what they do is different each time there is an error, but the table says what each one is for. If you want to see the table again, type 2Help* followed by 2P*. The 2Resume* (or 2Control-C*) command is often synonymous with 2Super-A*. But 2Resume* only proceeds, never aborts. If there is no way to proceed, just ways to abort, then 2Resume* does not do anything. The debugger knows about a current stack frame, and there are several commands that use it. The initially current stack frame is the one which signaled the error, either the one which got the microcode-detected error or the one which called 2ferror*, 2cerror*, or 2error*. When the debugger starts it up it shows you this frame in the following format: 3FOO:* 3 Arg 0 (X): 13* 3 Arg 1 (Y): 1* and so on. This means that 2foo* was called with two arguments, whose names (in the Lisp source code) are 2x* and 2y*. The current values of 2x* and 2y* are 213* and 21* respectively. These may not be the original arguments if 2foo* happens to 2setq* its argument variables. The 2Clear-Screen* (or 2Control-L*) command clears the screen, retypes the error message that was initially printed when the debugger was entered, and prints out a description of the current frame, in the above format. Several commands are provided to allow you to examine the Lisp control stack and to make frames current other than the one that got the error. The control stack (or ``regular pdl'') keeps a record of all functions currently active. If you call 2foo* at Lisp's top level, and it calls 2bar*, which in turn calls 2baz*, and 2baz* gets an error, then a backtrace (a backwards trace of the stack) would show all of this information. The debugger has two backtrace commands. 2Control-B* simply prints out the names of the functions on the stack; in the above example it would print 3BAZ  BAR  FOO  SI:*EVAL* 3  SI:LISP-TOP-LEVEL1  SI:LISP-TOP-LEVEL* The arrows indicate the direction of calling. The 2Meta-B* command prints a more extensive backtrace, indicating the names of the arguments to the functions and their current values; for the example above it might look like: 3BAZ:* 3 Arg 0 (X): 13* 3 Arg 1 (Y): 1* 3BAR:* 3 Arg 0 (ADDEND): 13* 3FOO:* 3 Arg 0 (FROB): (A B C . D)* and so on. The backtrace commands all accept numeric arguments which say how many frames to describe, the default being to describe all the frames. .need 1500 Moving around in the stack: The 2Control-N* command makes the ``next'' older frame be current. This is the frame which called the one that was current at before. The new current frame's function and arguments are printed in the format shown immediately above. 2Control-P* moves the current frame in the reverse direction. If you use it immediately after getting an error it selects frames that are part of the act of signaling. 2Meta-<* selects the frame in which the error occurred, the same frame that was selected when the debugger was entered. 2Meta->* selects the outermost or initial stack frame. 2Control-S* asks you for a string and searches down the stack (toward older frames) from the current frame for a frame whose executing function's name contains that string. That frame becomes current and is printed out. These commands are easy to remember since they are analogous to editor commands. The 2Control-Meta-N*, 2Control-Meta-P*, and 2Control-Meta-B* commands are like the corresponding 2Control* commands but don't censor the stack to omit ``uninteresting'' functions. When looking at interpreted code, the debugger usually tries to skip over frames that belong to the functions composing the interpreter, such as 2eval*, 2prog*, and 2cond*. 2Control-Meta-N*, 2Control-Meta-P*, and 2Control-Meta-B* show everything. They also show frames that are not yet active; that is, frames whose arguments are still being computed for functions that are going to be called. The 2Control-Meta-U* command goes down the stack (to older frames) to the next interesting function and makes that the current frame. 2Meta-L* prints out the current frame in ``full screen'' format, which shows the arguments and their values, the local variables and their values, and the machine code with an arrow pointing to the next instruction to be executed. Refer to 4(ASSEMBLER-0)How to Read Assembly Language* for help in reading this machine code. Commands such as 2Control-N* and 2Control-P*, which are useful to issue repeatedly, take a prefix numeric argument and repeat that many types. The numeric argument is typed by using 2Control* or 2Meta* and the number keys, as in the editor. Some other commands such as 2Control-M* also use the numeric argument; refer to the table at the end of the section for detailed information. .need 1500 Resuming execution: 2Meta-C* is similar to 2Control-C*, but in the case of an unbound variable or undefined function, actually 2setq*s the variable or defines the function, so that the error will not happen again. 2Control-C* (or 2Resume*) provides a replacement value but does not actually change the variable. 2Meta-C* proceeds using the proceed type 2:store-new-value*, and is available only if that proceed type is provided. 2Control-R* is used to return a value or values from the current frame; the frame that called that frame continues running as if the function of the current frame had returned. This command prompts you for each value that the caller expects; you can type either a form which evaluates to the desired value or 2End* if you wish to return no more values. The 2Control-T* command does a 2throw* to a given tag with a given value; you are prompted for the tag and the value. 2Control-Meta-R* 1reinvokes* the current frame; it starts execution at the beginning of the function, with the arguments currently present in the stack frame. These are the same arguments the function was originally called with unless either the function itself has changed them with 2setq* or you have set them in the debugger. If the function has been redefined in the meantime (perhaps you edited it and fixed its bug) the new definition is used. 2Control-Meta-R* asks for confirmation before resuming execution. 2Meta-R* is similar to 2Control-Meta-R* but allows you to change the arguments if you wish. You are prompted for the new arguments one by one; you can type a form which evaluates to the desired argument, or 2Space* to leave that argument unchanged, or 2End* if you do not want any more arguments. 2Space* is allowed only if this argument was previously passed, and 2End* is not allowed for a required argument. Once you have finished specifying the arguments, you must confirm before execution resumes. .need 1500 Stepping through function calls and returns: You can request a trap to the debugger on exit from a particular frame, or the next time a function is called. Each stack frame has a ``trap on exit'' bit. The 2Control-X* command toggles this bit. The 2Meta-X* command sets the bit to cause a trap for the current frame and all outer frames. If a program is in an infinite loop, this is a good way to find out how far back on the stack the loop is taking place. This also enables you to see what values are being returned. The 2Control-Meta-X* command clears the trap-on-exit bit for the current frame and outer frames. The 2Control-D* command proceeds like 2Control-C* but requests a trap the next time a function is called. The 2Meta-D* command toggles the trap-on-next-call bit for the erring stack group. It is useful if you wish to set the bit and then resume execution with something other than 2Control-C*. The function 2breakon* may be used to request a trap on calling a particular function. Trapping on entry to a frame automatically sets the trap-on-exit bit for that frame; use 2Control-X* to clear it if you do not want another trap. .need 1500 Transfering to other systems: 2Control-E* puts you into the editor, looking at the source code for the function in the current frame. This is useful when you have found the function that caused the error and that needs to be fixed. The editor command 2Control-Z* will return to the debugger, if it is still there. 2Control-M* puts you into the editor to mail a bug report. The error message and a backtrace are put into the editor buffer for you. A numeric argument says how many frames to include in the backtrace. 2Control-Meta-W* calls the window debugger, a display-oriented debugger. It is not documented in this manual, but should be usable without further documentation. .need 1500 Examining and setting the arguments, local variables, and values: 2Control-Meta-A* takes a numeric argument, 1n*, and prints out the value of the 1n*th argument of the current frame. It leaves 2** set to the value of the argument, so that you can use the Lisp 2read-eval-print* loop to examine it. It also leaves 2+* set to a locative pointing to the argument on the stack, so that you can change that argument (by calling 2rplacd* on the locative). 2Control-Meta-L* is similar, but refers to the 1n*th local variable of the frame. 2Control-Meta-V* refers to the 1n*th value this frame has returned (in a trap-on-exit). 2Control-Meta-F* refers to the function executing in the frame; it ignores its numeric argument and doesn't allow you to change the function. Another way to examine and set the arguments, locals and values of a frame is with the functions 2eh-arg*, 2eh-loc*, 2eh-val* and 2eh-fun*. Use these functions in expressions you evaluate inside the debugger, and they refer to the arguments, locals, values and function, respectively, of the debugger's current frame. The names 2eh:arg*, 2eh:val*, etc. are for compatibility with the Symbolics system. 3eh-arg* 1arg-number-or-name* 3eh:arg* 1arg-number-or-name* When used in an expression evaluated in the debugger, 2eh-arg* returns the value of the specifed argument in the debugger's current frame. Argument names are compared ignoring packages; only the pname of the symbol you supply is relevant. 2eh-arg* can appear in 2setf* and 2locf* to set an argument or get its location. 3eh-loc* 1local-number-or-name* 3eh:loc* 1local-number-or-name* Like 2eh-arg* but accesses the current frame's local variables instead of its arguments. 3eh-val* &optional 1value-number-or-name* 3eh:val* &optional 1value-number-or-name* 2eh-val* is used in an expression evaluated in the debugger when the current frame is returning multiple values, to examine those values. This is only useful if the function has already begun to return some values (as in a trap-on-exit), since otherwise they are all 2nil*. If a name is specified, it is looked for in the function's 2values* or 2return-list* declaration, if any. 2eh-val* can be used with 2setf* and 2locf*. You can make a frame return a specific sequence of values by setting all but the last value with 2eh-val* and doing 2Control-R* to return the last value. 2eh-val* with no argument returns a list of all the values this frame is returning. 3eh-fun* 3eh:fun* 2eh-fun* can be called in an expression being evalued inside the debugger to return the function-object being called in the current frame. It can be used with 2setf* and 2locf*. =Node: 4Summary of Commands* =Text: 3SUMMARY OF COMMANDS 2Control-A** Prints argument list of function in current frame. 2Control-Meta-A* Sets 2** to the 1n*th argument of the current frame. 2Control-B* Prints brief backtrace. 2Meta-B* Prints longer backtrace. 2Control-Meta-B* Prints longer backtrace with no censoring of ``uninteresting'' functions. 2Control-C or Resume* Attempts to continue, using the first proceed type on the list of available ones for this error. 2Meta-C* Attempts to continue, 2setq*'ing the unbound variable or otherwise ``permanently'' fixing the error. This uses the proceed type 2:store-new-value*, and is available only if that proceed type is. 2Control-D* Attempts to continue like 2Control-C*, but trap on the next function call. 2Meta-D* Toggles the flag that causes a trap on the next function call after you continue or otherwise exit the debugger. 2Control-E* Switches to Zmacs to edit the source code for the function in the current frame. 2Control-Meta-F* Sets 2** to the function in the current frame. 2Control-G or Abort* Quits to command level. This is not a command, but something you can type to escape from typing in an argument of a command. 2Control-Meta-H* Describes the condition handlers and resume handlers established by the current frame. 2Control-L or Clear-Screen* Redisplays error message and current frame. 2Meta-L* Displays the current frame, including local variables and compiled code. 2Control-Meta-L* Sets 2** to the value of local variable 1n* of the current frame. 2Control-M* Sends a bug report containing the error message and a backtrace of 1n* frames (default is 3). 2Control-N or Line* Moves to the next (older) frame. With argument, moves down 1n* frames. 2Meta-N* Moves to next frame and displays it like 2Meta-L*. With argument, move down 1n* frames. 2Control-Meta-N* Moves to next frame even if it is ``uninteresting'' or still accumulating arguments. With argument, moves down 1n* frames. 2Control-P or Return* Moves up to previous (newer) frame. With argument, moves up 1n* frames. 2Meta-P* Moves to previous frame and displays it like 2Meta-L*. With argument, moves up 1n* frames. 2Control-Meta-P* Moves to previous frame even if it is ``uninteresting'' or still accumulating arguments. With argument, moves up 1n* frames. 2Control-R* Returns a value or values from the current frame. 2Meta-R* Reinvokes the function in the current frame (restart its execution at the beginning), optionally changing the arguments. 2Control-Meta-R* Reinvokes the function in the current frame with the same arguments. 2Control-S* Searches for a frame containing a specified function. 2Meta-S* Reads the name of a special variable and returns that variable's value in the current frame. Instance variables of 2self* may also be specified even if not special. 2Control-Meta-S* Prints a list of special variables bound by the current frame and the values they are bound to by the frame. If the frame binds 2self*, all the instance variables of 2self* are listed even if they are not special. 2Control-T* Throws a value to a tag. 2Control-Meta-U* Moves down the stack to the previous ``interesting'' frame. 2Control-X* Toggles the flag in the current frame that causes a trap on exit or throw through that frame. 2Meta-X* Sets the flag causing a trap on exit or throw through the frame for the current frame and all the frames outside of it. 2Control-Meta-X* Clears the flag causing a trap on exit or throw through the frame for the current frame and all the frames outside of it. 2Control-Meta-V* Sets 2** to the 1n*th value being returned from the current frame. This is non-2nil* only in a trap on exit from the frame. 2Control-Meta-W* Switches to the window-oriented debugger. 2Control-Z or Abort* Aborts the computation and throw back to the most recent 2break* or debugger, to the program's command level, or to Lisp top level. 2? or Help* Prints debugger command self-documentation. 2Meta-<* Moves to the frame in which the error was signaled, and makes it current once again. 2Meta->* Moves to the outermost (oldest) stack frame. 2Control-0 through Control-Meta-9* Numeric arguments to the following command are specified by typing a decimal number with 2Control* and/or 2Meta* held down. 2Super-A, etc.* The commands 2Super-A*, 2Super-B*, etc. are assigned to all the available proceed types for this error. The assignments are different each time the debugger is entered, so it prints a list of them when it starts up. 2Help P* prints the list again. =Node: 4Deexposed Windows and Background Processes* =Text: 3DEEXPOSED WINDOWS AND BACKGROUND PROCESSES* If the debugger is entered in a window that is not exposed, a notification is used to inform you that it has happened. In general, a notification appears as a brief message printed inside square brackets if the selected window can print it. Otherwise, blinking text appears in the mouse documentation line telling you that a notification is waiting; to see the notification, type 2Terminal N* or select a window that can print it. In either case, an audible beep is made. In the case of a notification that the debugger is waiting to use a deexposed window, you can select and expose the window in which the error happened by typing 2Terminal 0 S*. You can do this even if the notification has not been printed yet because the selected window cannot print it. If you select the waiting window, in this way or in any other way, the notification is discarded since you already know what it was intended to tell you. If the debugger is entered in a process that has no window or other suitable stream to type out on, the window system assigns it a ``background window''. Since this window is initially not exposed, a notification is printed as above and you must use 2Terminal 0 S* to see the window. If an error happens in the scheduler stack group or the first level error handler stack group which are needed for processes to function, or in the keyboard or mouse process (both needed for the window system to function), the debugger uses the 1cold load stream*, a primitive facility for terminal I/O which bypasses the window system. If an error happens in another process but the window system is locked so that the notification mechanism cannot function, the cold load stream is used to ask what to do. You can tell the debugger to use the cold load stream immediately, to forcibly clear the window system locks and notify immediately as above, or to wait for the locks to become unlocked and then notify as above. If you tell it to wait, you can resume operation of the machine. Meanwhile, you can use the command 2Terminal Control-Clear-Input* to forcibly unlock the locks, or 2Terminal Call* to tell the debugger to use the cold load stream. The latter command normally enters a break-loop that uses the cold-load stream, but if there are any background errors, it offers to enter the debugger to handle them. You can also handle the errors in a Lisp listen loop of your choice by means of the function 2eh* (4(DEBUGGING-4)Entering the Debugger*), assuming you can select a functioning Lisp listen loop. =Node: 4Debugging after a Warm Boot* =Text: 3DEBUGGING AFTER A WARM BOOT* After a warm boot, the process that was running at the time of booting (or at the time the machine crashed prior to booting) may be debugged if you answer `no' when the system asks whether to reset that process. 3si:debug-warm-booted-process* Invoke the debugger, like the function 2eh* (4(DEBUGGING-4)Entering the Debugger*), on the process that was running as of the last warm boot (assuming there was such a process). On the CADR, the state you see in the debugger is not correct; some of the information dates from some period of time in advance of the boot or the crash. On the Lambda, the state you see in the debugger will, in some system version, be accurate.