From 0c83a574a0b425b7dfd3effd0e0d6383227a2500 Mon Sep 17 00:00:00 2001 From: Alain Schneble Date: Sat, 3 Sep 2016 12:08:11 +0200 Subject: [PATCH] Revise DEBUG doc on how to get control to the debugger * etc/DEBUG: Revise section 'Getting control to the debugger'. Restructure exisiting content into subsections and add further documentation related to how signals can be used to get control back to the debugger. --- etc/DEBUG | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 21 deletions(-) diff --git a/etc/DEBUG b/etc/DEBUG index 656e29a..e4390c0 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -190,45 +190,83 @@ kick in, provided that you run under GDB. ** Getting control to the debugger +*** Breakpoints + +Setting a breakpoint is the usual way to configure a point in the +program's execution thread where control will be returned to the +debugger. It is therefore wise to add breakpoints just after Emacs +has been loaded into the debugger, but before it is actually run. + '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 would fire the debugger, breaking at 'maybe_call_debugger' is useful. +'Fredraw_display' is another convenient function. It is one that is +rarely called and which you can invoke at will interactively with "M-x +redraw-display RET". + +*** Signal interception + It is useful, when debugging, to have a guaranteed way to return to -the debugger at any time. When using X, this is easy: type C-z at the -window where Emacs is running under GDB, and it will stop Emacs just -as it would stop any ordinary program. When Emacs is running in a -terminal, things are not so easy. +the debugger at any time. This allows adding or removing breakpoints +or inspecting Emacs's state at an arbitrary point in time. + +GDB intercepts all signals sent to the debuggee (aka inferior) and +gives control over what will happen with those: whether or not control +is returned to GDB, a message is printed or if it shall be passed to +the inferior when continuing execution. -The src/.gdbinit file in the Emacs distribution arranges for SIGINT -(C-g in Emacs) to be passed to Emacs and not give control back to GDB. -On modern POSIX systems, you can override that with this command: +The src/.gdbinit file in the Emacs distribution arranges for SIGINT to +be passed to Emacs and not give control back to GDB. This is +especially useful for an Emacs debuggee running in a terminal, as it +is configured to send a SIGINT as response to C-g keystroke. On +modern POSIX systems, you can override that with this command: handle SIGINT stop nopass After this 'handle' command, SIGINT will return control to GDB. If -you want the C-g to cause a QUIT within Emacs as well, omit the 'nopass'. +you want this signal to cause a QUIT within Emacs running in a +terminal as well, omit the 'nopass'. + +To list the configuration of all signals, use this command: + + info signal A technique that can work when 'handle SIGINT' does not is to store the code for some character into the variable stop_character. Thus, set stop_character = 29 -makes Control-] (decimal code 29) the stop character. -Typing Control-] will cause immediate stop. You cannot -use the set command until the inferior process has been started. -Put a breakpoint early in 'main', or suspend the Emacs, -to get an opportunity to do the set command. +makes Control-] (decimal code 29) the stop character. Typing +Control-] will cause a SIGTSTP to be sent to the Emacs debuggee +itself. You cannot use the set command until the inferior process has +been started as it refers to a global variable in the Emacs debuggee +process. Put a breakpoint early in 'main', or suspend Emacs, to get +an opportunity to do the set command. + +You can also send a signal to the inferior Emacs at any time by using +kill. For instance, to send a SIGTSTP, invoke the following command +from a shell: + + kill -TSTP [Inferior-Emacs-PID] + +Depending on the 'handle' configuration, this might also give control +back to GDB. If so, the signal can be suppressed from being forwarded +to the inferior and Emacs resumed by invoking the command 'signal 0'; +regardeless of the active 'pass' / 'nopass' configuration. To +substitute it with another signal, use 'signal [SIGNAME]' instead. -Another technique for get 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". +*** Emacs running in a terminal -When Emacs is running in a terminal, it is sometimes useful to use a separate -terminal for the debug session. This can be done by starting Emacs as usual, -then attaching to it from gdb with the 'attach' command which is explained in -the node "Attach" of the GDB manual. +When Emacs is running in a terminal, typing C-g will either send a +SIGINT or a SIGQUIT signal to the Emacs process. And it arranges for +both SIGINT and SIGQUIT to cause a QUIT within Emacs. + +It is sometimes useful to use a separate terminal for the debug +session. This can be done by starting Emacs as usual, then attaching +to it from gdb with the 'attach' command which is explained in the +node "Attach" of the GDB manual. Another approach is shown under +'Debugging the TTY (non-windowed) version' below. On MS-Windows, you can start Emacs in its own separate terminal by setting the new-console option before running Emacs under GDB: @@ -236,6 +274,40 @@ setting the new-console option before running Emacs under GDB: (gdb) set new-console 1 (gdb) run +*** Emacs running under a window system + +When Emacs is running under a window system, reception of a SIGINT and +SIGQUIT will cause it to terminate. It might therefore be useful to +configure the 'handle' command for those signals to use 'nopass', to +prevent Emacs from terminating on reception of such signals. + +When using a window system, there is no reason for Emacs to handle C-g +as a SIGINT, as keyboard input is processed by the window system's +message pump. Hence, no signal is sent as a response to a C-g. + +When using X, type C-z at the window where Emacs is running under GDB, +and it will stop Emacs just as it would stop any ordinary program. + +On MS-Windows, starting Emacs in its own separate terminal even when +running as a GUI application will allow you to send a Ctrl-c or +Ctrl-Break to the console. GDB treats them as a SIGINT, but Emacs +won't terminate as it ignores these events. + +*** Signals sent to GDB + +There is a sublety in GDB about how it handles SIGINT signals sent to +itself: it simply forwards them to the inferior process. Hence, +hitting C-c in the terminal used by GDB is a very convenient way to +interrupt Emacs and -- depending on 'handle SIGINT' setup -- return +control to the debugger. When debugging with GDB in Emacs, you can +use comint-interrupt-subjob command bound to 'C-c C-c' by default to +get the same result. + +On MS-Windows, GDB will turn a C-c into a DebugBreakProcess call if +Emacs is running in a separate terminal or it will just ignore it +otherwise, as the event will be received by Emacs anyway when running +under the same terminal as GDB. + ** Examining Lisp object values. When you have a live process to debug, and it has not encountered a -- 2.9.1