GNU bug report logs - #46586
26.3, 27.1.50; Emacs crash in a backtrace (core) dump (a long standing issue)

Previous Next

Package: emacs;

Reported by: 路客 <luke.yx.lee <at> gmail.com>

Date: Wed, 17 Feb 2021 10:15:02 UTC

Severity: normal

Found in version 26.3

Fixed in version 29.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 46586 in the body.
You can then email your comments to 46586 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#46586; Package emacs. (Wed, 17 Feb 2021 10:15:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to 路客 <luke.yx.lee <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 17 Feb 2021 10:15:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: 路客 <luke.yx.lee <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 26.3, 27.1.50; Emacs crash in a backtrace (core) dump (a long
 standing issue)
Date: Wed, 17 Feb 2021 18:13:56 +0800
Hi all,

I found a short data clip can always crash Emacs 26.3 or 27.1.50 with
a terminal backtrace (core) dump in the "read()" function. It took me
a few hours to narrow it down and finally reach this minimal crashing
data set:

----- code begin -----
(#1=(#("000008964 .gnus.el" 0 18 (r #1#))
(def #2=#("000008964 .gnus.el" 0 18
(r
(#2#
(def #3=#("000006393 .gnus.el" 0 18
(r #4=(#3#
(def
#("000006393 .gnus.el" 0 18 (r #4#)) "x"))))"x"))))"x")))
----- code end -----

Try to `read' or `eval' this block of code (C-x C-e) will immediately
crash Emacs 26.3 or 27.1.50; however, older Emacs 26.0.50 works well
by entering the debugger with an error like:

----- elisp debugger message begin -----
Debugger entered--Lisp error: (invalid-function (#("000008964
.gnus.el" 0 18 (r #1)) (def #("000008964 .gnus.el" 0 18 (r (#3 (def
#("000006393 .gnus.el" 0 18 (r (#7 (def #("000006393 .gnus.el" 0 18 (r
#9)) "x")))) "x")))) "x")))
  ((#("000008964 .gnus.el" 0 18 (r #1)) (def #("000008964 .gnus.el" 0
18 (r (#3 (def #("000006393 .gnus.el" 0 18 ...) "x")))) "x")))
  eval(((#("000008964 .gnus.el" 0 18 (r #2)) (def #("000008964
.gnus.el" 0 18 (r (#4 (def #("000006393 .gnus.el" 0 18 ...) "x"))))
"x"))) nil)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)
----- elisp debugger message end -----

Funny thing is that if I change any of the above ".gnus.el" to another
file name, Emacs won't crash and is able to enter the debugger like
26.0.50. Is there anything special about the ".gnus.el" ?

This short crashing code block was actually a lot longer as a part of
a big bookmark file, and has long ago started to crash newer Emacs
than 26.0.50. I didn't know the root cause till these days I decided
to figure that out and finally extracted that block out and simplified
it to this simple form.

Could anyone help fix this long standing issue? Thanks.

-- 
Best regards,
Luke Lee




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46586; Package emacs. (Wed, 17 Feb 2021 16:05:02 GMT) Full text and rfc822 format available.

Message #8 received at 46586 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: 路客 <luke.yx.lee <at> gmail.com>
Cc: 46586 <at> debbugs.gnu.org
Subject: Re: bug#46586: 26.3, 27.1.50;
 Emacs crash in a backtrace (core) dump (a long standing issue)
Date: Wed, 17 Feb 2021 18:04:37 +0200
> From: 路客 <luke.yx.lee <at> gmail.com>
> Date: Wed, 17 Feb 2021 18:13:56 +0800
> 
> ----- code begin -----
> (#1=(#("000008964 .gnus.el" 0 18 (r #1#))
> (def #2=#("000008964 .gnus.el" 0 18
> (r
> (#2#
> (def #3=#("000006393 .gnus.el" 0 18
> (r #4=(#3#
> (def
> #("000006393 .gnus.el" 0 18 (r #4#)) "x"))))"x"))))"x")))
> ----- code end -----
> 
> Try to `read' or `eval' this block of code (C-x C-e) will immediately
> crash Emacs 26.3 or 27.1.50; however, older Emacs 26.0.50 works well
> by entering the debugger with an error like:

It's an infinite recursion in substitute_object_recurse, called by
lread--substitute-object-in-subtree.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46586; Package emacs. (Thu, 18 Feb 2021 01:57:01 GMT) Full text and rfc822 format available.

Message #11 received at 46586 <at> debbugs.gnu.org (full text, mbox):

From: 路客 <luke.yx.lee <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 46586 <at> debbugs.gnu.org
Subject: Re: bug#46586: 26.3, 27.1.50; Emacs crash in a backtrace (core) dump
 (a long standing issue)
Date: Thu, 18 Feb 2021 09:56:06 +0800
> It's an infinite recursion in substitute_object_recurse, called by
> lread--substitute-object-in-subtree.

I see, but why is Emacs 26.0.50 or earlier able to catch this issue?
Shouldn't the read() function try to prevent itself from crashing?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46586; Package emacs. (Thu, 18 Feb 2021 14:17:01 GMT) Full text and rfc822 format available.

Message #14 received at 46586 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: 路客 <luke.yx.lee <at> gmail.com>
Cc: 46586 <at> debbugs.gnu.org, Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#46586: 26.3, 27.1.50; Emacs crash in a backtrace (core) dump
 (a long standing issue)
Date: Thu, 18 Feb 2021 16:16:23 +0200
> From: 路客 <luke.yx.lee <at> gmail.com>
> Date: Thu, 18 Feb 2021 09:56:06 +0800
> Cc: 46586 <at> debbugs.gnu.org
> 
> > It's an infinite recursion in substitute_object_recurse, called by
> > lread--substitute-object-in-subtree.
> 
> I see, but why is Emacs 26.0.50 or earlier able to catch this issue?

The related code was refactored since then.  (And I'm not sure Emacs
26.0.50 indeed identified the problem correctly, see below.  So it
could be just sheer luck that it didn't crash back then.)

> Shouldn't the read() function try to prevent itself from crashing?

It should, so this is a bug.

But how did such a form get originated?  It looks like it's indeed
self-referential, and thus is got to trigger infinite recursion:

> (#1=(#("000008964 .gnus.el" 0 18 (r #1#))
> (def #2=#("000008964 .gnus.el" 0 18
> (r
> (#2#
> (def #3=#("000006393 .gnus.el" 0 18
> (r #4=(#3#
> (def
> #("000006393 .gnus.el" 0 18 (r #4#)) "x"))))"x"))))"x")))

The last part references itself: it seems to define a string with a
text property that is the same string.

Stepping through the code in substitute_object_recurse, I see that we
end up recursively expanding this string:

  #("000006393 .gnus.el" 0 18 (r (#("000006393 .gnus.el" 0 18 (r #2)) (def #0 "x"))))

Which then yields this:

  #("000006393 .gnus.el" 0 18 (r (#0 (def #("000006393 .gnus.el" 0 18 (r #2)) "x"))))

And that again yields

  #("000006393 .gnus.el" 0 18 (r (#("000006393 .gnus.el" 0 18 (r #2)) (def #0 "x"))))

Etc. etc., ad nauseam (or, rather, until we exhaust the C run-time
stack and segfault).

Does anyone see how to stop this infinite recursion, except by
counting recursive invocation levels and bailing out at some arbitrary
depth?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46586; Package emacs. (Thu, 18 Feb 2021 14:46:02 GMT) Full text and rfc822 format available.

Message #17 received at 46586 <at> debbugs.gnu.org (full text, mbox):

From: Andreas Schwab <schwab <at> linux-m68k.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 46586 <at> debbugs.gnu.org, 路客 <luke.yx.lee <at> gmail.com>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#46586: 26.3, 27.1.50; Emacs crash in a backtrace (core)
 dump (a long standing issue)
Date: Thu, 18 Feb 2021 15:45:01 +0100
On Feb 18 2021, Eli Zaretskii wrote:

> Does anyone see how to stop this infinite recursion, except by
> counting recursive invocation levels and bailing out at some arbitrary
> depth?

Shouldn't the subst->seen list prevent recursion?

Andreas.

-- 
Andreas Schwab, schwab <at> linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46586; Package emacs. (Thu, 18 Feb 2021 15:01:01 GMT) Full text and rfc822 format available.

Message #20 received at 46586 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Andreas Schwab <schwab <at> linux-m68k.org>
Cc: 46586 <at> debbugs.gnu.org, luke.yx.lee <at> gmail.com, monnier <at> iro.umontreal.ca
Subject: Re: bug#46586: 26.3, 27.1.50; Emacs crash in a backtrace (core)
 dump (a long standing issue)
Date: Thu, 18 Feb 2021 17:00:50 +0200
> From: Andreas Schwab <schwab <at> linux-m68k.org>
> Cc: 路客 <luke.yx.lee <at> gmail.com>,  46586 <at> debbugs.gnu.org,
>   Stefan Monnier
>  <monnier <at> iro.umontreal.ca>
> Date: Thu, 18 Feb 2021 15:45:01 +0100
> 
> On Feb 18 2021, Eli Zaretskii wrote:
> 
> > Does anyone see how to stop this infinite recursion, except by
> > counting recursive invocation levels and bailing out at some arbitrary
> > depth?
> 
> Shouldn't the subst->seen list prevent recursion?

Maybe, but the insertion into the 'seen' list is conditioned on #n=
being in 'completed'.  Or maybe I don't understand the logic of the
code well enough.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46586; Package emacs. (Fri, 17 Jun 2022 15:27:02 GMT) Full text and rfc822 format available.

Message #23 received at 46586 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: 路客 <luke.yx.lee <at> gmail.com>
Cc: 46586 <at> debbugs.gnu.org
Subject: Re: bug#46586: 26.3, 27.1.50; Emacs crash in a backtrace (core)
 dump (a long standing issue)
Date: Fri, 17 Jun 2022 17:25:57 +0200
路客 <luke.yx.lee <at> gmail.com> writes:

> I found a short data clip can always crash Emacs 26.3 or 27.1.50 with
> a terminal backtrace (core) dump in the "read()" function. It took me
> a few hours to narrow it down and finally reach this minimal crashing
> data set:
>
> ----- code begin -----
> (#1=(#("000008964 .gnus.el" 0 18 (r #1#))
> (def #2=#("000008964 .gnus.el" 0 18
> (r
> (#2#
> (def #3=#("000006393 .gnus.el" 0 18
> (r #4=(#3#
> (def
> #("000006393 .gnus.el" 0 18 (r #4#)) "x"))))"x"))))"x")))
> ----- code end -----
>
> Try to `read' or `eval' this block of code (C-x C-e) will immediately
> crash Emacs 26.3 or 27.1.50; however, older Emacs 26.0.50 works well
> by entering the debugger with an error like:

(I'm going through old bug reports that unfortunately weren't resolved
at the time.)

I can reproduce this problem in Emacs 28.1, but not in Emacs 29 -- the
reader/printer/gc was recently rewritten to handle recursive structures
better, so I'm closing this bug report.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




bug marked as fixed in version 29.1, send any further explanations to 46586 <at> debbugs.gnu.org and 路客 <luke.yx.lee <at> gmail.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Fri, 17 Jun 2022 15:27:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 16 Jul 2022 11:24:12 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 283 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.