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


View this message in rfc822 format

From: Pip Cet <pipcet <at> protonmail.com>
To: Gerd Möllmann <gerd.moellmann <at> gmail.com>
Cc: oscarfv <at> eclipso.eu, 79200 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca
Subject: 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 today.

Previous Next


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