Subject: Re: bug#22790: 24.5; Infinite loop involving malloc called from signal handler

From: Eli Zaretskii <[email-masked]>
Date: Fri, 04 Mar 2016 17:16:54 +0200

> Date: Fri, 4 Mar 2016 16:23:17 +0200
> Cc: [email-masked]
> From: Andreas Gustafsson <[email-masked]>
> 
> > In any case, this code is run as part of the so-called "emergency
> > escape", when you type C-g more than once while Emacs is busy doing
> > something that cannot be interrupted.  In that situation, we are way
> > past the point where invoking undefined behavior is of any concern,
> > because the only thing we can do then is auto-save and commit
> > suicide.
> 
> Not necessarily - there is also the option of continuing what emacs
> was doing, which is what I would have done, by answering both the
> "Auto-save?" and "Abort (and dump core)?" prompts with "no", if those
> prompts had actually appeared.  But they didn't, because emacs entered
> an infinite loop trying to print them.

Is it really a fact that the loop _followed_ the C-g, not the other
way around?  If there was no loop before the C-g, then why would you
type C-g?

> > You need to use "finish", not "step" or "stepi".
> 
> I will try that the next time the lockup happens, but I'm quite sure
> it won't do anything useful.
> 
> > I don't think the loop can reasonably be inside libpthread,
> 
> Why not?

Because it's much more likely that Emacs has bugs that lead to
infloops than that libpthread has such bugs.

> We are talking undefined behavior here, after all.

If libpthread was so prone to undefined behavior, it would have been
either fixed long time ago or thrown away in favor of a more robust
implementation.

I'm not saying such a bug in libpthread is impossible, just that it's
much less likely than a bug in Emacs.

> If you find looping in libpthread surprising, just wait until the
> nasal demons appear :) It could be something as simple as trying to
> acquire a spinlock that was already held when the signal occurred.

It could be anything.  But I generally find that the probability of a
bug in an application is much higher than in a library everyone uses.

> > so you should try
> > getting back to the Emacs application code and out of calls to library
> > functions.  Typing "finish" repeatedly until you are in some Emacs
> > code is the way to achieve that.
> 
> It won't be able do that since it's in an infinite loop inside
> libpthread.

If you can show that, it might be an evidence that the loop is indeed
inside that library.  Did you actually try that?  If not, please do,
it's important to know where Emacs loops.

> > > Even if you consider the backtrace to be suspect, code inspection
> > > should suffice to show that the line
> > > 
> > >           printf ("Auto-save? (y or n) ");
> > > 
> > > in src/keyboard.c can be executed from a signal handler.
> > 
> > Indeed, it can.  But I don't think this is the reason for the problem
> > you are describing.  That code cannot be entered unless you type C-g
> > twice or more in a TTY session while Emacs is already in some
> > un-interruptible loop or system call.  It is that loop or system call
> > that we need to identify in order to fix this problem.
> 
> As far as I'm concerned, this bug report is specifically about what
> happens after the SIGINT, not what happened before it.

I was under the impression that the loop happens regardless; apologies
if I misunderstood.  But if you think it is caused by the emergency
exit procedure, how about commenting out those printf's and running
with the modified version for a while?  If the loops don't happen,
then it will be another evidence in favor of your hypothesis about the
reasons for this.

In any case, if those printf's are the culprit, they are no longer
there in the current sources of what will soon become Emacs 25.1.
They were replaced with direct calls to 'write'.  So if we are sure
there's no other problem that causes these loops, we can close this
bug.

> Could the auto-save have failed due to interruption by yet another
> (earlier) control-g?

Not according to my reading of the code, but I could be wrong, and
it's hard to test this in real usage.