Subject: bug#15575: 24.3.50; New tty menus crash Emacs

From: Eli Zaretskii <[email-masked]>
Date: Wed, 09 Oct 2013 22:00:34 +0300

> From: Jan Djärv <[email-masked]>
> Date: Wed, 9 Oct 2013 19:58:57 +0200
> Cc: [email-masked]
> 
> (gdb) p from->used[0]
> $1 = 30065
> (gdb) p from->used[1]
> $2 = 26977
> (gbd) p from->used[2]
> $3 = 12140

I don't see how this could be true, I guess the compiler fools the
debugger here.

> (gdb) p to->used[0]
> $7 = 4
> (gdb) p to->used[1]
> $8 = 0
> (gdb) p to->used[2]
> $9 = 0

Likewise, this doesn't seem to be possible on a TTY.  Sigh...

> (gdb) p to->glyphs[0]
> $10 = (struct glyph *) 0x4
> (gdb) p to->glyphs[1]
> $11 = (struct glyph *) 0x4
> (gdb) p to->glyphs[2]
> $12 = (struct glyph *) 0x4

Neither can this be true, I think.  Or maybe I'm missing something.

> (gdb) p sizeof(struct glyph)
> $13 = 48

This one is the only one that makes sense, but it's not a variable, so
I'm not surprised.

> These values vary if run again.   Here is another run:
> 
> $1 = 12346
> $2 = 384
> $3 = 1
> $4 = (struct glyph *) 0x3000000000000088
> $5 = (struct glyph *) 0x100f11e21
> $6 = (struct glyph *) 0x10180300a
> $7 = 12346
> $8 = 384
> $9 = 1
> $10 = (struct glyph *) 0x104033e00
> $11 = (struct glyph *) 0x1040c48e0
> $12 = (struct glyph *) 0x1040c90e0
> $13 = 48
> $14 = 12731
> $15 = 0

Can you try the patch below?

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2013-10-08 17:49:20 +0000
+++ src/xdisp.c	2013-10-09 18:44:38 +0000
@@ -20589,11 +20589,14 @@ display_menu_bar (struct window *w)
 static void
 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
 {
-  int area, i, sum_used = 0;
+  int area, i;
   struct glyph *pointers[1 + LAST_AREA];
 
   /* Save glyph pointers of TO.  */
   memcpy (pointers, to->glyphs, sizeof to->glyphs);
+  eassert (to->used[0] == from->used[0]);
+  eassert (to->used[1] == from->used[1]);
+  eassert (to->used[2] == from->used[2]);
 
   /* Do a structure assignment.  */
   *to = *from;
@@ -20601,22 +20604,10 @@ deep_copy_glyph_row (struct glyph_row *t
   /* Restore original pointers of TO.  */
   memcpy (to->glyphs, pointers, sizeof to->glyphs);
 
-  /* Count how many glyphs to copy and update glyph pointers.  */
+  /* Count how many glyphs to copy and copy the glyphs.  */
   for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
-    {
-      if (area > LEFT_MARGIN_AREA)
-	{
-	  eassert (from->glyphs[area] - from->glyphs[area - 1]
-		   == from->used[area - 1]);
-	  to->glyphs[area] = to->glyphs[area - 1] + to->used[area - 1];
-	}
-      sum_used += from->used[area];
-    }
-
-  /* Copy the glyphs.  */
-  eassert (sum_used <= to->glyphs[LAST_AREA] - to->glyphs[LEFT_MARGIN_AREA]);
-  for (i = 0; i < sum_used; i++)
-    to->glyphs[LEFT_MARGIN_AREA][i] = from->glyphs[LEFT_MARGIN_AREA][i];
+    for (i = 0; i < from->used[area]; i++)
+      to->glyphs[area][i] = from->glyphs[area][i];
 }
 
 /* Display one menu item on a TTY, by overwriting the glyphs in the