debug is a Lisp machine stack back-trace debugger.
- Choose the way to initiate debugger. E.g. call
debug-on-entryand choose a function. See bellow for other options.
- Do some operation that should eventually call the function.
- In the backtrace inspect the state, step through, look at locals, evaluate expressions etc. See bellow for useful shortcuts.
- Initiating debugger - useful shortcuts/functions
debug-on-error- enters the debugger if an error is found.
debug-on-entry- starts debugger when entering the given function. Multiple function can be given by calling this function many times. To remove a function use
debug-on-message- this is a variable. If non-nil it is interpreted as a regex which is matched against printed messages and it breaks into debugger if a match is found. Useful if you see a message printed and would like to investigate the location.
debug-watch- run debugger when variable changes. To remove use function
- In addition, a call to
(debug)can be used in the code to break into debugger. Thus, find a place where
debugcall won’t introduce side-effects and insert it. Don’t forget to re-evaluate
defunafter change (
eval-defun). Also, don’t forget to remove
(debug)call and re-evaluate
defunagain when finished debugging.
- Useful shortcuts/functions in the backtrace buffer
g l - debugger-list-functions- list function instrumented to break into.
p - debugger-toggle-locals- show/hide local variables for the given stack frame.
z o - backtrace-multi-line- pretty-print the stack backtrace line.
z c - backtrace-single-line- returns to a single line representation (undo previous).
g b - debugger-frame- request entry to debugger when the frame exits. Will be marked with asterisk at the left side.
u - debugger-frame-clear- undo previous command.
d - debugger-step-through- make a step through subexpressions evaluations.
c - debugger-continue- continue evaluating without stopping. Stop on the next marked frame with
r - debugger-return-value-
E - debugger-eval-expression- evaluate given expression in the context of the stack frame at point. For investigating local variables see
debugger-toggle-localsabove. This should be checked!
backtrace-goto-source- this should go to the source location of the current stack frame, but it’s not working at the moment which is pity as it would really make a huge difference.
edebug is a source-level debugger. It provides a step-by-step execution through
the source code.
Breaking into debugger is performed using the code instrumentation, i.e. the original code is replaced with a slightly modified code which calls the debugger.
- Useful shortcuts/functions
SPC u , e d - eval-defunwith universal prefix - instrument current function. Evaluating without the prefix will remove instrumentation.
edebug can record an execution trace capturing in a
*edebug-trace* buffer each
function called with parameters and return values.
edebug-trace to non-nil to enable this mode.
This is handy to find out a call path to the interesting place for investigation.
Profiling is used to figure out why the code is running slow and to find critical places to optimize.
But, I find it also a convenient method to figure out a flow of control inside of a piece of complex code I’m not familiar with. I just run the profiler and then invoke a functionality I would like to investigate. After that, profiler will give me a nice tree of calls so I will quickly be able to figure out what functions are important and their dependencies.
Is navigation to the exact location in the source code possible?
To start the profiler run
profiler-start. Then, invoke functionality that is
under inspection. After that run
profiler-report to get the report. Don’t forget
profiler-stop as the profiler introduces small run-time overhead.
- Emacs Info on Elisp -
SPC h i or M-x info- follow