Bug 14449

Summary: A key gets stuck in OpenGL applications
Product: xorg Reporter: James Andrewartha <trs80>
Component: Server/GeneralAssignee: Peter Hutterer <peter.hutterer>
Status: RESOLVED DUPLICATE QA Contact: Xorg Project Team <xorg-team>
Severity: major    
Priority: medium CC: chalserogers, sndirsch, ThJaeger
Version: 7.3 (2007.09)   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
patch none

Description James Andrewartha 2008-02-09 21:51:11 UTC
As reported in http://bugs.winehq.org/show_bug.cgi?id=11195 https://bugs.launchpad.net/ubuntu/+source/wine/+bug/178817 and https://bugs.edge.launchpad.net/ubuntu/+source/xorg/+bug/190615 while playing some games, occasionally a key will get stuck and repeat forever, until the X server is restarted. This was originally thought to be a wine bug, but it continues after wine exits and also happens with Frets on Fire (written in Python). In my case, unplugging and replugging the keyboard has no effect.

I'm running Xorg 7.3 from Debian unstable, with nvidia 100.14.19-1, others have reported it under Ubuntu hardy.
Comment 1 Christopher James Halse Rogers 2008-03-21 16:08:55 UTC
More info is available in https://bugs.edge.launchpad.net/ubuntu/+source/xorg-server/+bug/194214 .  In particular, it seems that this bug is triggered by simultaneous keyboard and mouse press activity, and is not restricted to OpenGL applications (but is more easily reproducible under Compiz).

An easy way to reproduce is to hold down a key (say page_down) and then scroll madly with the mousewheel in (for example) firefox - trying this one or more times should result in page_down being stuck.  Repeating this procedure a couple of times can unstick the key, but input handling is still broken - some modifier (alt, super) keys don't work.

I tried to git-bisect this problem, and ended up with the following git revisions as candidates:
a53172827c69a88155a088843c9a3e8a7a7a0463
b76b1d51fe3053fa2a60b64de9ac93f50ef252f5
83e76fb3f7a89a237893c2b7df450d4f90eab52d
b600e7c123ce637359a75c43bf67b3462eadb37e
15117d47bf883f3eefc57404f1dfc0c933ab054a

I couldn't do any better, because these all fail to build.

I have tried to reproduce on git head, but the nvidia binary blob doesn't work there, and I find it hard to reproduce without compiz.
Comment 2 Tom Jaeger 2008-03-22 12:55:09 UTC
A little bit of additional information: The bug is definitely not in xf86-input-kbd (or in the kernel),  keys get "stuck" despite the input module properly calling xf86PostKeyboardEvent.

I guess everybody has their own way of reproducing the issue, here's how I do it:
* Press any key
* Wait a moment to trigger auto-repeat (this seems necessary)
* Open a bunch of tabs in firefox.
* Release the key while pages are still being loaded

I can only reproduce the issue under compiz as well, but there are reports on the ubuntu bug-tracker of people running a 2d window managers.

Unfortunately, I couldn't get git master to run either (I always end up with unresolved symbols in the intel driver).
Comment 3 Tom Jaeger 2008-03-23 23:00:24 UTC
Okay, so the bug starts happening when FreezeThaw is called with frozen = true inside an UNWRAP/COND_WRAP pair.  I can't see a problem with that right now, but I guess it means that the server will be thawed inside such a pair as well, which allows the the processInputProc that FreezeThaw set (EnqueueEvent) to escape, resulting in an endless loop of events being bounced around (I can't see where the repeating would come from, and in fact I don't see any repeats when compiling from git).  It seems that this patch would solve the issue.

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 167dbec..0352006 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -263,7 +263,7 @@ typedef struct
        device->unwrapProc = unwrapproc;
 
 #define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs, backupproc) \
-        backupproc = device->public.processInputProc; \
+        backupproc = device->public.realInputProc; \
        device->public.processInputProc = oldprocs->processInputProc; \
        device->public.realInputProc = oldprocs->realInputProc; \
        device->unwrapProc = oldprocs->unwrapProc;

It's not well-tested by any means, and considering that I only started looking at the code today (and that this (un)wrapping stuff very complex),  it's possible that it might introduce new bugs.  In particular, I haven't checked how well it jibes with Xevie.  My head hurts already.
Comment 4 Tom Jaeger 2008-03-24 13:41:39 UTC
Created attachment 15433 [details] [review]
patch

XevIE gets this right, saving and conditionally restoring realInputProc as opposed to processInputProc.

Also, a similar thing is happening in xkbUnwrapProc, not sure if this creates a problem, but the attached patch addresses this issue as well.
Comment 5 Tom Jaeger 2008-03-24 22:08:17 UTC
Marking this as a duplicate of bug #13511, since they have the same cause.  Of course, I didn't realize that the other bug existed until I searched git commits for realInputProc...

*** This bug has been marked as a duplicate of bug 13511 ***
Comment 6 Stefan Dirsch 2008-04-07 09:19:40 UTC
*** Bug 14811 has been marked as a duplicate of this bug. ***

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.