GNU bug report logs - #79200
31.0.50; Duplicated elements for '#<marker at' in buffer-undo-list

Previous Next

Package: emacs;

Reported by: Óscar Fuentes <oscarfv <at> eclipso.eu>

Date: Fri, 8 Aug 2025 16:45:03 UTC

Severity: normal

Found in version 31.0.50

Full log


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

From: Pip Cet <pipcet <at> protonmail.com>
To: Gerd Möllmann <gerd.moellmann <at> gmail.com>
Cc: Óscar Fuentes <oscarfv <at> eclipso.eu>,
 "Pip Cet via \"Bug reports for GNU Emacs,
 the Swiss army knife of text editors\"" <bug-gnu-emacs <at> gnu.org>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>, 79200 <at> debbugs.gnu.org
Subject: Re: bug#79200: 31.0.50;
 Duplicated elements for '#<marker at' in buffer-undo-list
Date: Sat, 09 Aug 2025 10:50:10 +0000
Gerd Möllmann <gerd.moellmann <at> gmail.com> writes:

> Pip Cet via "Bug reports for GNU Emacs, the Swiss army knife of text
> editors" <bug-gnu-emacs <at> gnu.org> writes:
>
>> Well, compact_undo_list is a nop with HAVE_MPS:
>>
>> static Lisp_Object
>> compact_undo_list (Lisp_Object list)
>> {
>> #ifndef HAVE_MPS
>>   Lisp_Object tail, *prev = &list;
>>
>>   for (tail = list; CONSP (tail); tail = XCDR (tail))
>>     {
>>       if (CONSP (XCAR (tail))
>> 	  && MARKERP (XCAR (XCAR (tail)))
>> 	  && !vectorlike_marked_p (&XMARKER (XCAR (XCAR (tail)))->header))
>> 	*prev = XCDR (tail);
>>       else
>> 	prev = xcdr_addr (tail);
>>     }
>> #endif
>>   return list;
>> }
>>
>> We still truncate undo lists, but we don't "compact" them, i.e. treat
>> them as weak structures and remove markers that are referred to only in
>> undo lists. Correct?
>
> I think you are correct. buffer_step -> compact_buffer ->
> truncate_undo_list, but no compact.
>
>> The "obvious" fix would be to use a weak hash table to associate undo
>> information with markers rather than keeping them in the undo
>> list. However, that sounds quite hard to do, and it might make undo a
>> lot more expensive.
>
> Hm, yes that sounds hard. Hm.
>
> Do you think we could, in compact, locally keep track of markers already
> seen, and coalesce their entries somehow? My memory of the undo stuff is
> pretty hazy, alas, and probably outdated, too.

So far, I've seen no markers showing up twice in the same section of the
undo list; that would be a bug in BUF_MARKERS, I think. So I'm not sure
how coalescing would work.

Over here, most of the markers in the undo list appear to be constructed
in the format_mode_line_unwind_data function. So maybe something like
this is needed:

From d5cf17f88fbba4cdfc61ebea725e12a2c8b9aa42 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet <at> protonmail.com>
Date: Sat, 9 Aug 2025 10:32:19 +0000
Subject: [PATCH] Detach markers explicitly so they don't wind up on the undo
 list

* src/xdisp.c (unwind_format_mode_line): Detach markers when we're
done with them.
---
 src/xdisp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/xdisp.c b/src/xdisp.c
index 432dd5dceca..2406bb6f3d9 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13828,6 +13828,7 @@ unwind_format_mode_line (Lisp_Object vector)
 
 	      current_buffer = XBUFFER (buffer);
 	      set_point_from_marker (AREF (vector, 11));
+	      detach_marker (AREF (vector, 11));
 	      ASET (vector, 11, Qnil);
 	      current_buffer = cb;
 	    }
-- 
2.50.0

Famous last words: I think this is safe and AREF (vector, 11) is never
leaked to Lisp. And I'm not sure whether the only reason it helps here
might be a local peculiarity...

Of course, none of this is very satisfying: we can perform manual memory
management for markers in C code, but it's very hard to do so from Lisp
code.

Pip





This bug report was last modified 1 day ago.

Previous Next


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