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

From: Iurie Marian <[email-masked]>
Date: Wed, 26 Feb 2025 21:36:55 +0100

Alright! This change fixes the issue!
It works with gcc 12.2 as well!

Thank you very much, Pip!

KR,
Iurie

On Wed, 26 Feb 2025 at 21:24, Pip Cet <[email-masked]> wrote:

> Pip Cet <[email-masked]> writes:
>
> > "Iurie Marian" <[email-masked]> writes:
> >
> >> Yes, it looks like Michael's changes have nothing to do with this bug,
> >> but these seem just to reveal some undefined behavior... idk. Btw,
> >> just by commenting the line src/keyboard.c:11697, it is not crashing
> >> anymore; maybe this could be a hint.
> >>
> >>> gcc --version
> >> gcc (Debian 12.2.0-14) 12.2.0
> >>
> >>> Can you check that 0x555555cf0b00 is a valid dpyinfo structure?
> >> (gdb) info locals
> >> event = 0x555555953aa0 <kbd_buffer+384>
> >> copy = {kind = SELECTION_REQUEST_EVENT, dpyinfo = 0x55c82260, requestor
> = 0x555555f93a80, selection = 0x45, target = 0x4d, property =
> >> 0x5e, time = 0}
> >> moved_events = <optimized out>
> >>
> >> (gdb) x 0x555555c82260
> >> 0x555555c82260: 0x00
> >
> > Well, that only tells us the first byte is 0, which is probably correct.
> > Can you retry with x/64gx 0x555555c82260 (or the new address) so we see
> > some more data?
> >
> >>> Can you run "ptype/o struct selection_input_event" [...]
> >>
> >> (gdb) ptype/o struct selection_input_event
> >> /* offset      |    size */  type = struct selection_input_event {
> >> /*      0: 0   |       4 */    enum event_kind kind : 16;
> >> /* XXX  6-byte hole      */
> >
> > 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?
>
> Investigating the undefined behavior bug theory further, I find that
> applying this patch changes the code emitted for evq_flush (I think this
> is strange, since evq_flush doesn't call kbd_buffer_store_event, it
> calls kbd_buffer_store_buffered_event!).
>
> diff --git a/src/keyboard.h b/src/keyboard.h
> index 5e04b54eb74..c1c75cc7ea5 100644
> --- a/src/keyboard.h
> +++ b/src/keyboard.h
> @@ -505,10 +505,9 @@ #define EVENT_HEAD_KIND(event_head) \
>  kbd_buffer_store_event_hold (struct input_event *event,
>                              struct input_event *hold_quit)
>  {
> -  static_assert (alignof (struct input_event) == alignof (union
> buffered_input_event)
> -                && sizeof (struct input_event) == sizeof (union
> buffered_input_event));
> -  kbd_buffer_store_buffered_event ((union buffered_input_event *) event,
> -                                  hold_quit);
> +  union buffered_input_event bie;
> +  bie.ie = *event;
> +  kbd_buffer_store_buffered_event (&bie, hold_quit);
>  }
>  extern void poll_for_input_1 (void);
>  extern void show_help_echo (Lisp_Object, Lisp_Object, Lisp_Object,
>
> Can you confirm whether it changes anything for you?
>
> Pip
>
>