Hello list!
On X11, sometimes, when you move your mouse and release the keyboard
key at the same time, you get a SIGSERV crash. (see dumps and demo
program at the end)
I’ve “tracked” it down to the X11_KeyRepeat function in
SDL_x11events.c. The function looks for next X11 event in the queue and
compares it to the current one, working around keyboard auto-repeat
feature of X11.
The culprit is XPeekEvent, which either crashes itself, either
corrupts something, so next XNextEvent call crashes.
Now, as far as I can tell, SDL does everything correctly. So it might
be a bug in libX11 or my video driver.
However, some things are a bit weird. This never happens with SDL1.2,
altho I compared the code for X11_KeyRepeat and related and it looked
very very similar…
Additionally, something tells me this doesn’t happen for regular X11
programs, but I don’t have any proof for this yet, going to try it next.
Also, if I remove the SDL_Delay() call, the bug seems to be gone, so I
might be doing something wrong in the first place. Are SDL_Delay()
calls not considered good practice in SDL2 ?
I’d be very grateful if you guys would test this. If you’re not seeing
the crash, you can change the “2” in the following line to “10” or a
larger value, makes it easier to trigger:
src/video/x11/SDL_x11events.c:113
((peekevent.xkey.time-event->xkey.time) < 2)) {
You’re aiming to “inject” a MotionNotify event inbetween the
KeyRelease and the auto-repeated KeyPress. For me, it crashes reliably
when this happens.
(I use libX11 1.4.1 and nvidia-driver 295.49)
test program:
#include <SDL.h>
int main(int argc, char* argv[])
{
SDL_Window* window;
SDL_Renderer *renderer;
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("X11_KeyPreat problem",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
512, 512,
SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 0xFF, 0, 0, 255);
SDL_RenderClear(renderer);
int done = 0;
while (!done) {
SDL_Event event;
SDL_zero(event);
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) done = 1;
}
SDL_RenderPresent(renderer);
//SDL_Delay(10);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
gdb backtrace:
#0 0xb7fe1424 in __kernel_vsyscall ()
#1 0xb7d85451 in raise () from /lib/libc.so.6
#2 0xb7d86b92 in abort () from /lib/libc.so.6
#3 0xb7dc09f5 in ?? () from /lib/libc.so.6
#4 0xb7dc6861 in ?? () from /lib/libc.so.6
#5 0xb7dc966d in ?? () from /lib/libc.so.6
#6 0xb7dcb27c in malloc () from /lib/libc.so.6
#7 0xb7c3944c in _XStoreEventCookie () from /usr/lib/libX11.so.6
#8 0xb7c284bc in XPeekEvent () from /usr/lib/libX11.so.6
#9 0xb7fa46a5 in XPeekEvent (a=0x804e788, b=0xbfffeccc)
at …/src/video/x11/SDL_x11sym.h:94
#10 0xb7fb519b in X11_KeyRepeat (_this=0x804dd58)
at …/src/video/x11/SDL_x11events.c:110
#11 X11_DispatchEvent
(_this=0x804dd58)at …/src/video/x11/SDL_x11events.c:444
#12 X11_PumpEvents (_this=0x804dd58)
at …/src/video/x11/SDL_x11events.c:914
#13 0xb7f33c84 in SDL_PumpEvents () at …/src/events/SDL_events.c:309
#14 0xb7f341ba in SDL_WaitEventTimeout (event=0xbfffef90,timeout=0)
at …/src/events/SDL_events.c:342
#15 0xb7f34295 in SDL_PollEvent(event=0xbfffef90)
at …/src/events/SDL_events.c:324 #16 0x080488e8 in main (argc=1,
argv=0xbffff094) at event.c:22
Relevant valgrind output:
==32494== Invalid write of size 1
==32494== at 0x4027164: memcpy
==32494== by 0x486C3F4: ??? (in /usr/lib/libXi.so.6.1.0)
==32494== by 0x472E7C7:_XCopyEventCookie(in /usr/lib/libX11.so.6.3.0)
==32494== by 0x471E481: XPeekEvent (in /usr/lib/libX11.so.6.3.0)
==32494== by 0x40D06A4: XPeekEvent (SDL_x11sym.h:94)
==32494== by 0x40E119A: X11_PumpEvents (SDL_x11events.c:110)
==32494== by 0x405FC83: SDL_PumpEvents (SDL_events.c:309)
==32494== by 0x40601B9: SDL_WaitEventTimeout (SDL_events.c:342)
==32494== by 0x4060294: SDL_PollEvent (SDL_events.c:324)
==32494== by 0x80488E7: main(event.c:22)
==32494== Address 0x707f29b is 7 bytes after a block of size 60 alloc’d
==32494== at 0x402582E: malloc
==32494== by 0x486C341: ??? (in /usr/lib/libXi.so.6.1.0)
==32494== by 0x472E7C7:_XCopyEventCookie(in /usr/lib/libX11.so.6.3.0)
==32494== by 0x471E481: XPeekEvent (in /usr/lib/libX11.so.6.3.0)
==32494== by 0x40D06A4: XPeekEvent (SDL_x11sym.h:94)
==32494== by 0x40E119A: X11_PumpEvents (SDL_x11events.c:110)
==32494== by 0x405FC83: SDL_PumpEvents (SDL_events.c:309)
==32494== by 0x40601B9: SDL_WaitEventTimeout (SDL_events.c:342)
==32494== by 0x4060294: SDL_PollEvent (SDL_events.c:324)
==32494== by 0x80488E7: main(event.c:22)–
driedfruit