GNU bug report logs - #76559
31.0.50; [-O3 + PGTK] Crash when 'copying as kill'/'killing word'

Previous Next

Package: emacs;

Reported by: Iurie Marian <marian.iurie <at> gmail.com>

Date: Tue, 25 Feb 2025 17:34:01 UTC

Severity: normal

Merged with 76729

Found in version 31.0.50

Full log


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

From: Po Lu <luangruo <at> yahoo.com>
To: Pip Cet <pipcet <at> protonmail.com>
Cc: Michael Albinus <michael.albinus <at> gmx.de>,
 Iurie Marian <marian.iurie <at> gmail.com>, 76559 <at> debbugs.gnu.org
Subject: Re: bug#76559: 31.0.50; [-O3 + PGTK] Crash when 'copying as
 kill'/'killing word'
Date: Thu, 27 Feb 2025 13:35:17 +0800
Pip Cet <pipcet <at> protonmail.com> writes:

> This is strange, but it looks like this may be a C undefined behavior
> bug (or, less likely, an actual GCC bug).  If the event_kind bitfield is
> listed with size 4, shouldn't the hole after it be listed with size 4,
> not size 6?

I'm afraid that must be a Gdb or GCC debuginfo generation bug, since the
total size of the structure is 56.  Whereas the aggregate of the values
printed by GDB is 58.

> Here's the code obtained by disass/s evq_flush which copies the relevant
> part of the header:
>
> 3810	      *kbd_store_ptr = *event;
>    0x00000000002f9f4c <+108>:	movd   %xmm0,(%rdx)
>    0x00000000002f9f50 <+112>:	movdqa 0x20(%rsp),%xmm4
>    0x00000000002f9f56 <+118>:	movdqa 0x10(%rsp),%xmm5
>    0x00000000002f9f5c <+124>:	movq   %xmm1,0x4(%rdx)

If kbd_buffer_store_buffered_event is forcibly inlined, my GCC 12.2.0
generates virtually identical machine code to yours:

   0x000000000067fd8c <+188>:	mov    0x1f653d(%rip),%rdi        # 0x8762d0 <event_q.lto_priv.0>
   0x000000000067fd93 <+195>:	movd   (%rdi),%xmm0
   0x000000000067fd97 <+199>:	movdqu 0x10(%rdi),%xmm2
   0x000000000067fd9c <+204>:	movdqu 0x28(%rdi),%xmm3
   0x000000000067fda1 <+209>:	movq   0x4(%rdi),%xmm1
   0x000000000067fda6 <+214>:	mov    0x20(%rdi),%r14
   0x000000000067fdaa <+218>:	mov    0x38(%rdi),%r13
[...]
   0x000000000067fdb4 <+228>:	movaps %xmm2,0x20(%rsp)
   0x000000000067fdb9 <+233>:	movaps %xmm3,0x10(%rsp)

[...]

   0x000000000067fd27 <+87>:	movd   %xmm0,(%rdx) ;; bytes 0-3
   0x000000000067fd2b <+91>:	movdqa 0x20(%rsp),%xmm4
   0x000000000067fd31 <+97>:	movdqa 0x10(%rsp),%xmm5
   0x000000000067fd37 <+103>:	movq   %xmm1,0x4(%rdx) ;; bytes 4-11
   0x000000000067fd4a <+122>:	mov    %r14,0x20(%rdx) ;; bytes 32-39
   0x000000000067fd4e <+126>:	mov    %r13,0x38(%rdx) ;; bytes 56-63
   0x000000000067fd52 <+130>:	movups %xmm4,0x10(%rdx) ;; bytes 16-31
   0x000000000067fd56 <+134>:	movups %xmm5,0x28(%rdx) ;; bytes 40-55

You'll observe that the gap coincides exactly with the padding in struct
input_event.  This is the RTL GCC produces just as it is lowered from
optimized expression trees:

(insn 582 581 583 62 (set (mem:V2HI (reg/f:DI 106 [ _68 ]) [66 MEM <vector(2) short unsigned int> [(union buffered_input_event *)_68]+0 S4 A32])
        (reg:V2HI 170 [ vect_ev_kind_24.71 ])) "keyboard.c":3810:22 -1
     (nil)) ;; bytes 0-3
(insn 583 582 584 62 (set (mem:V2SI (plus:DI (reg/f:DI 106 [ _68 ])
                (const_int 4 [0x4])) [66 MEM <vector(2) unsigned int> [(union buffered_input_event *)_68 + 4B]+0 S8 A32])
        (reg:V2SI 167 [ vect_ev_ie_code_157.76 ])) "keyboard.c":3810:22 -1
     (nil)) ;; bytes 4-11
(insn 584 583 585 62 (set (mem:V2DI (plus:DI (reg/f:DI 106 [ _68 ])
                (const_int 16 [0x10])) [66 MEM <vector(2) long unsigned int> [(union buffered_input_event *)_68 + 16B]+0 S16 A64])
        (reg:V2DI 164 [ vect_ev_ie_x_134.83 ])) "keyboard.c":3810:22 -1
     (nil)) ;; bytes 16-31
(insn 585 584 586 62 (set (mem:DI (plus:DI (reg/f:DI 106 [ _68 ])
                (const_int 32 [0x20])) [66 MEM <Time> [(union buffered_input_event *)_68 + 32B]+0 S8 A64])
        (reg:DI 84 [ ev$ie$timestamp ])) "keyboard.c":3810:22 -1
     (nil)) ;; bytes 32-39
(insn 586 585 587 62 (set (mem:V2DI (plus:DI (reg/f:DI 106 [ _68 ])
                (const_int 40 [0x28])) [66 MEM <vector(2) long unsigned int> [(union buffered_input_event *)_68 + 40B]+0 S16 A64]) ;; bytes 40-55
        (reg:V2DI 163 [ vect_ev_ie_frame_or_window_11.90 ])) "keyboard.c":3810:22 -1
     (nil))
(insn 587 586 588 62 (set (mem/f:DI (plus:DI (reg/f:DI 106 [ _68 ])
                (const_int 56 [0x38])) [66 MEM <struct Lisp_X *> [(union buffered_input_event *)_68 + 56B]+0 S8 A64])
        (reg/f:DI 110 [ ev$ie$device ])) "keyboard.c":3810:22 -1
     (nil)) ;; bytes 56-63

Judging by the expression names, it's clearly copying only the `struct
input_event' union member.  In fact, this erroneous code is generated as
soon as SRA processes aggregate references.

  MEM <short unsigned int> [(union buffered_input_event *)_68] = ev$kind_24;
  MEM <short unsigned int> [(union buffered_input_event *)_68 + 2B] = ev$ie$part_10;
  MEM <unsigned int> [(union buffered_input_event *)_68 + 4B] = ev$ie$code_157;
  MEM <unsigned int> [(union buffered_input_event *)_68 + 8B] = ev$ie$modifiers_58;
  MEM <struct Lisp_X *> [(union buffered_input_event *)_68 + 16B] = ev$ie$x_134;
  MEM <struct Lisp_X *> [(union buffered_input_event *)_68 + 24B] = ev$ie$y_90;
  MEM <Time> [(union buffered_input_event *)_68 + 32B] = ev$ie$timestamp_23;
  MEM <struct Lisp_X *> [(union buffered_input_event *)_68 + 40B] = ev$ie$frame_or_window_11;
  MEM <struct Lisp_X *> [(union buffered_input_event *)_68 + 48B] = ev$ie$arg_78;
  MEM <struct Lisp_X *> [(union buffered_input_event *)_68 + 56B] = ev$ie$device_77;

What I suspect is that there is some CU in which `struct
selection_input_event' is incomplete or fails to appear in `union
buffered_input_event' and that that misleads the compiler during
link-time recompilation.  But I could be far off the mark, since I am
very much out of touch with contemporary GCC.




This bug report was last modified 109 days ago.

Previous Next


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