=== modified file 'doc/emacs/trouble.texi' --- doc/emacs/trouble.texi 2011-01-25 04:08:28 +0000 +++ doc/emacs/trouble.texi 2011-03-29 17:47:26 +0000 @@ -812,6 +812,14 @@ This backtrace is useful for debugging such long loops, so if you can produce it, copy it into the bug report. address@hidden debug-on-special-event +If the normal quit process is ineffective, you can try sending Emacs +the special event given in @code{debug-on-special-event}, which by +default corresponds to SIGUSR2. When Emacs receives this event, it +stops what it's doing, sets @code{debug-on-quit} to @code{t}, and +tries to break into the debugger in a variety of ways. This process +happens even in places where quitting is normally not allowed. + @item Check whether any programs you have loaded into the Lisp world, including your @file{.emacs} file, set any variables that may affect the === modified file 'doc/lispref/debugging.texi' --- doc/lispref/debugging.texi 2011-01-25 04:08:28 +0000 +++ doc/lispref/debugging.texi 2011-03-29 17:46:44 +0000 @@ -185,6 +185,20 @@ when you quit. @xref{Quitting}. @end defopt address@hidden debug-on-special-event +When this variable contains a symbol matching one of the special +events in @code{special-event-map} (@pxref{Active Keymaps}) and Emacs +receives the corresponding event, Emacs will break into the debugger +instead of processing the event normally, setting @code{debug-on-quit} +to @code{t} as a side effect. This feature is useful for terminating +infinite loops in places where quits would normally be ignored, such +as in code that runs during redisplay. + +Currently, the only events Emacs recognizes as valid values for address@hidden are @code{sigusr1} and @code{sigusr2}. + address@hidden defopt + @node Function Debugging @subsection Entering the Debugger on a Function Call @cindex function call debugging === modified file 'lisp/cus-start.el' --- lisp/cus-start.el 2011-03-27 10:55:07 +0000 +++ lisp/cus-start.el 2011-03-29 17:36:51 +0000 @@ -259,6 +259,11 @@ (suggest-key-bindings keyboard (choice (const :tag "off" nil) (integer :tag "time" 2) (other :tag "on"))) + (debug-on-special-event debug + (choice (const :tag "None" nil) + (const :tag "When sent SIGUSR1" sigusr1) + (const :tag "When sent SIGUSR2" sigusr2)) + "24.1") ;; This is not good news because it will use the wrong ;; version-specific directories when you upgrade. We need === modified file 'src/keyboard.c' --- src/keyboard.c 2011-03-27 02:27:11 +0000 +++ src/keyboard.c 2011-03-29 17:29:47 +0000 @@ -7165,12 +7165,33 @@ { int old_errno = errno; struct user_signal_info *p; + const char* special_event_name = NULL; SIGNAL_THREAD_CHECK (sig); - + + if (SYMBOLP (Vdebug_on_special_event) && + STRINGP (XSYMBOL (Vdebug_on_special_event)->xname)) + { + special_event_name = + SSDATA (XSYMBOL (Vdebug_on_special_event)->xname); + } + for (p = user_signals; p; p = p->next) if (p->sig == sig) { + if (special_event_name && + strcmp (special_event_name, p->name) == 0) + { + /* Enter the debugger in many ways. */ + debug_on_next_call = 1; + debug_on_quit = 1; + Vquit_flag = Qt; + Vinhibit_quit = Qnil; + + /* Eat the event. */ + break; + } + p->npending++; #ifdef SIGIO if (interrupt_input) @@ -12178,6 +12199,17 @@ `deactivate-mark' call uses this to set the window selection. */); Vsaved_region_selection = Qnil; + DEFVAR_LISP ("debug-on-special-event", + Vdebug_on_special_event, + doc: /* Enter debugger on this special event. +When Emacs receives the special event specifed by this variable, +it will try to break into the debugger as soon as possible instead of +processing the event normally through `special-event-map'. + +Currently, the only meaningful values for this +variable are `sigusr1' and `sigusr2'. */); + Vdebug_on_special_event = intern_c_string ("sigusr2"); + /* Create the initial keyboard. */ initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); init_kboard (initial_kboard); === modified file 'src/lisp.h' --- src/lisp.h 2011-03-27 02:27:11 +0000 +++ src/lisp.h 2011-03-28 13:06:41 +0000 @@ -2814,7 +2814,7 @@ /* Defined in eval.c */ extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qdefun, Qmacro; -extern Lisp_Object Qinhibit_quit; +extern Lisp_Object Qinhibit_quit, Qdebug; extern Lisp_Object Vautoload_queue; extern Lisp_Object Vsignaling_function; extern int handling_signal;