Subject: bug#17986: 24.3.92; Evaluating (setq default-directory nil) freezes Emacs

From: Eli Zaretskii <[email-masked]>
Date: Tue, 15 Jul 2014 17:27:48 +0300

> From: Stephen Berman <[email-masked]>
> Cc: [email-masked]
> Date: Tue, 15 Jul 2014 13:41:02 +0200
> 
> On Sun, 13 Jul 2014 17:54:35 +0300 Eli Zaretskii <[email-masked]> wrote:
> 
> >> From: Stephen Berman <[email-masked]>
> >> Date: Thu, 10 Jul 2014 14:27:30 +0200
> >> 
> >> 0. Start Emacs with -Q or -Q -D
> >> 1. Type (setq default-directory nil) in *scratch* and evaluate it.
> >> => Emacs freezes uninterruptibly and uses up to 90% CPU; I have to kill
> >> it from outside.
> >
> > Should be fixed in revision 117376 on the emacs-24 branch.
> 
> For the record, I confirm that this fixes it; thanks.

Thanks for verification.

> > When Emacs becomes unresponsive, it is best to attach a debugger to a
> > running Emacs process, and then use the procedure described in
> > etc/DEBUG (under "If the symptom of the bug is that Emacs fails to
> > respond") to find out which function infloops; then include this
> > information in the bug report.
> 
> I tried doing this, but neither with `s' nor with `f' did gdb show what
> I could recognize as an infloop (`f' always went straight to frame #0,
> and `s' never got to a loop, though I entered it very many times).  Is
> there something more specific I could do the next time?

etc/DEBUG doesn't say to use `s' and `f', it says to use 'finish' and
'next'.  'f' is not an abbreviation of 'finish', it is an abbreviation
of 'frame'.  Also, 'step', or 's', is not useful in this situation,
because it simply undoes what you did with 'finish', by getting you
deeper and deeper into the code from which you just emerged.

The idea of that procedure is to first find the function where Emacs
loops, by repeated 'finish' commands until 'finish' doesn't return,
i.e. does not print a higher frame number and the value returned by
the lower frame.  Then step with 'next' through the looping function
and see why it loops, i.e. why it fails to return.  (In this case, it
failed to return because displaying the mode line signaled an error,
which immediately triggered another redisplay.)