• Aucun résultat trouvé

Debugging and Profiling

Dans le document Writing GNU Emacs Extensions (Page 184-187)

In this appendix:

• Evaluation

• The Debugger

• Edebug

• The Profiler

This appendix describes some facilities in Emacs for testing and debugging your Lisp programs.

Evaluation

A Lisp expression in any buffer can be evaluated by placing the cursor at the end of the expression and pressing C-x C-e (eval-last-sexp). The keystroke M-:

(eval-expression) prompts for a Lisp expression to evaluate in the minibuffer. You can also use the commands eval-region and eval-current-buffer.

The *scratch* buffer is normally in Lisp Interaction mode (and if it isn't, it can be put in that mode with M-x lisp-interaction-mode RET). In that mode, C-j is normally

eval-print-last-sexp, which is like eval-last-sexp except that it also inserts the result of evaluation into the buffer. Also in Lisp Interaction mode is C-M-x,

eval-defun, which evaluates the "defun" that point is in. The meaning of "defun" in this context is broad; it means the enclosing Lisp expression (if there is one) that begins with an open-parenthesis at the left margin. Finally, Lisp Interaction mode allows you to type partial Lisp symbols and complete them with M-TAB.

Lisp expressions can also be placed in files and loaded with load, load-file, load-library, and require.

The Debugger

Emacs Lisp has a built-in debugging mode that can be invoked automatically under certain circumstances. Entering the debugger is controlled as follows.

Page 196

debug-on-entry

This is a command. It prompts (with completion) for the name of a function. Whenever that function is invoked, Emacs will enter the debugger.

debug-on-error

This is a variable. If it is non-nil, then Emacs will enter the debugger whenever an error is signaled.

debug-on-next-call

This is a variable. If it is non-nil, Emacs will enter the debugger the very next time an expression is to be evaluated.

debug-on-quit

This is a variable. If it is non-nil, Emacs will enter the debugger whenever a "quit" is signaled (e.g., when the user presses C-g).

When the debugger is invoked, a window displaying the Lisp stack appears. In this buffer, called *Backtrace*, each line represents a pending function call, with the top lines representing more recent calls. You can see the pending Lisp expressions, test the values of variables and other expressions in different contexts, and force a function to return a certain value.

These are the useful debugging-mode commands.

c

Leave the debugger, continuing whatever code was interrupted by entering it. This isn't possible when the debugger was invoked because of an error.

q

Leave the debugger, aborting the pending computation.

d

Continue execution until the next function call, then reenter the debugger.

e

Prompt for a Lisp expression to evaluate in the context of the topmost stack ''frame."

b

"Break" when returning from the current function. If the debugger is invoked when a function is called, then this command will continue execution until the same function is about to return, then will reenter the debugger.

r

When about to return from a function, prompt for a Lisp expression to be that function's return value (instead of whatever value it computed).

Page 197

Edebug

Edebug is an elaborate debugging environment that is far more powerful than the debugging facilities described in the previous section. It allows you to step through the actual source code of a running Lisp program. Edebug is an amazing piece of work written entirely in Lisp; it's a testament both to the talents of its author, Daniel LaLiberte, and to the expressive power of Emacs Lisp, which provides enough access to its own internals to make such a tool possible.

This section is only a brief summary of Edebug. For complete information, refer to the Edebug section of The GNU Emacs Lisp Reference Manual. Details on obtaining it are in Appendix D, Obtaining and Building Emacs.

To use Edebug, you must select those functions that you specifically wish to be able to trace.

Each function must be individually instrumented, which means evaluating it in a special way.

The command edebug-defun performs this task, and is used like eval-defun. The variable edebug-all-defs (q.v.) controls whether loading Edebug should redefine the various eval- commands to do instrumenting as well.

After instrumenting the desired functions, leave their definitions available in some buffer. You can uninstrument functions by re-evaluating their definitions in the ordinary way.

Edebug is activated whenever any instrumented function is called. A window showing the function's definition appears, along with a little arrow in the left margin indicating on what line execution has stopped. The cursor will be placed at the beginning of the expression that is about to be invoked (but if you wish, you can move the cursor, or even hide the buffer, without affecting the operation of Edebug).

At this point, you're in Edebug mode and can execute the following commands:

c

Continue execution.

q

Abort execution and leave Edebug.

SPC

Single-step. If Edebug is stopped at a variable or a constant, move past it and show its value. If Edebug is stopped at the beginning of a function call, move inside the function call. Subsequent single-steps will move over each argument, showing their values. If Edebug is stopped at a point where all the arguments to a function have been evaluated, then single-stepping calls that function with those arguments and displays the result. If that function is also

Page 198

instrumented, single-stepping will descend into it. At each step, the cursor moves to the appropriate point in the source code.

n

Next. Like single-step, but evaluates nested, instrumented functions without descending into them.

e

Prompt for an expression to evaluate in the context of the stopped program.

h

"Continue to here." If you place the cursor in a spot in the source code where you'd like to stop, h will cause the program to continue execution until it reaches that spot.

d

Display a backtrace, similar in appearance to Emacs's *Backtrace* buffer (see the previous section) but without the functionality. (Edebug commands continue to work.)

b

Set a breakpoint at the location of the cursor. The program will stop any time it reaches that point.

u

Unset a breakpoint.

x

Set a conditional breakpoint. You'll be prompted for a Lisp expression. Each time this breakpoint is reached, if the expression is true, the program will stop.

Edebug has many more capabilities than the few listed here, but these are the most-often-used features.

The Profiler

Profiling a program is the process of figuring out how much time different parts of it take to run, presumably in a quest to make it more efficient. Barry Warsaw has written an ingenious package for profiling Emacs Lisp called ELP.

Like Edebug, ELP relies on functions being "instrumented." This is done with the command elp-instrument-function, which prompts for a function name. There's also

elp-instrument-package, which prompts for a prefix. Any existing functions whose names begin with the given prefix will get instrumented.

Functions are uninstrumente with elp-restore-function and elp-restore-all.

Page 199

To use ELP, simply run your program after instrumenting the functions you wish to profile.

Profiling data will accumulate silently. When you're ready to see the results so far, run the command elp-results. A buffer will appear, showing, for each profiled function, the number of times it was called, the total time spent in the function, and the average time per call.

Use elp-reset-function to set a function's call-count and elapsed-time counters back to zero; elp-reset-all does this for all profiles functions.

Page 200

C

Dans le document Writing GNU Emacs Extensions (Page 184-187)