1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-05 22:20:24 -08:00

New debugger-trap function to break to GDB

* src/eval.c: new primitive debugger-trap
* src/.gdbinit: set breakpoint to Fdebugger_trap
* etc/DEBUG: document it.
Remove suggestion to use Fredraw_display.

This do-nothing primitive gives control to GDB, and for debugging
convenience a breakpoint is set by default in .gdbinit.
This commit is contained in:
Jeremy Bryant 2025-07-23 23:35:01 +01:00 committed by Eli Zaretskii
parent b6f177b68a
commit caa6bc95c1
3 changed files with 27 additions and 5 deletions

View file

@ -211,16 +211,17 @@ the debugger, but before running it, is the most efficient way of
making sure control will be returned to the debugger when you need making sure control will be returned to the debugger when you need
that. that.
There is a default function to give control to the debugger. It is
called debugger-trap. This is a do-nothing primitive, as a convenient
point to return control to the debugger. You can invoke interactively
with "M-x debugger-trap RET". The src/.gdbinit file in the Emacs source
distribution sets a breakpoint on this function.
'Fsignal' is a very useful place to put a breakpoint in. All Lisp 'Fsignal' is a very useful place to put a breakpoint in. All Lisp
errors go through there. If you are only interested in errors that errors go through there. If you are only interested in errors that
would fire the Lisp debugger, breaking at 'maybe_call_debugger' is would fire the Lisp debugger, breaking at 'maybe_call_debugger' is
useful. useful.
Another technique for getting control to the debugger is to put a
breakpoint in some rarely used function. One such convenient function
is Fredraw_display, which you can invoke at will interactively with
"M-x redraw-display RET".
It is also useful to have a guaranteed way to return to the debugger It is also useful to have a guaranteed way to return to the debugger
at any arbitrary time. When using X, this is easy: type C-z at the at any arbitrary time. When using X, this is easy: type C-z at the
window where you are interacting with GDB, and it will stop Emacs just window where you are interacting with GDB, and it will stop Emacs just

View file

@ -1314,6 +1314,11 @@ if defined_WINDOWSNT
end end
end end
# Break at default trap function to give control to GDB.
# Call from Emacs with M-x debugger-trap
break Fdebugger_trap
# Put the Python code at the end of .gdbinit so that if GDB does not # Put the Python code at the end of .gdbinit so that if GDB does not
# support Python, GDB will do all the above initializations before # support Python, GDB will do all the above initializations before
# reporting an error. # reporting an error.

View file

@ -3091,6 +3091,21 @@ FUNCTIONP (Lisp_Object object)
return false; return false;
} }
DEFUN ("debugger-trap", Fdebugger_trap, Sdebugger_trap, 0, 0, "",
doc: /* Trap execution flow and hand over control to GDB.
The Emacs source file src/.gdbinit uses this via the GDB command
"break Fdebugger_trap".
This function has no effect. It is reserved for debugging, and is not
called by Emacs otherwise.
For Lisp debugging see debug, as well as edebug, in the manual:
"(elisp) Debugging". */)
(void)
{
return Qnil;
}
Lisp_Object Lisp_Object
funcall_general (Lisp_Object fun, ptrdiff_t numargs, Lisp_Object *args) funcall_general (Lisp_Object fun, ptrdiff_t numargs, Lisp_Object *args)
{ {
@ -4617,4 +4632,5 @@ alist of active lexical bindings. */);
defsubr (&Sspecial_variable_p); defsubr (&Sspecial_variable_p);
DEFSYM (Qfunctionp, "functionp"); DEFSYM (Qfunctionp, "functionp");
defsubr (&Sfunctionp); defsubr (&Sfunctionp);
defsubr (&Sdebugger_trap);
} }