GNOME Bugzilla – Bug 429907
gnome-keyboard-properties crashed with SIGSEGV in draw_key() when trying to add new layout.
Last modified: 2007-12-11 23:50:46 UTC
The bug has been opened on https://bugs.launchpad.net/ubuntu/+source/control-center/+bug/101895 "... Just ran into this problem on a fully updated AMD64 running Feisty myself. Attached is the core dump from gdb (apport didn't catch it), backtrace is coming. Need this functionality to work around a bug when running full-screen games under Cedega (us-intl layout doesn't work right). To reproduce, open gnome-keyboard-properties, click "Layouts", click "Add". Program dies every time. Following is the output from the terminal, which may also help: mbt@sage:~$ gnome-keyboard-properties dpy: 0x63f8f0 evt/error/major/minor: 113/174/1/0 (gnome-keyboard-properties:14444): GnomeKbdIndicator-WARNING **: key AE00: keycode = 4294967295; not in range 8..255 Segmentation fault (core dumped) mbt@sage:~$ ... http://librarian.launchpad.net/7330921/bt-gkp.txt gnome-keyboard-properties backtrace from gdb ...
+ Trace 127905
what is the keyboard model? what is the exact libgnomekbd version? is there any way to reproduce it in 32bit environment?
I actually have the "Microsoft Natural Keyboard Pro USB / Microsoft Internet Keyboard Pro", and I suspect that it is the non-square layout that is causing the problem... Switching to generic solves the crash. This is with: Package: gnome-control-center Source: control-center Version: 1:2.18.1-0ubuntu2 Package: libgnomekbd1 Source: libgnomekbd Version: 2.18.1-0ubuntu1 I am afraid I do not know if this can be reproduced in a 32bit environment, as I do not have access to a 32bit install.
I just tried your config - I setup the keyboard to be MS Natural Pro USB - and I can add layouts without any trouble. Which means I cannot reproduce your problem:( BTW in my code the line 872 is not in draw_key but in draw_key_label - and I cannot see why would anything on that line could cause the crash. Sebastien, can you reproduce this one?
(In reply to comment #3) > I just tried your config - I setup the keyboard to be MS Natural Pro USB - and > I can add layouts without any trouble. Which means I cannot reproduce your > problem:( Do you have a 32bit or 64bit system? > BTW in my code the line 872 is not in draw_key but in draw_key_label - and I > cannot see why would anything on that line could cause the crash. I did not generate that stacktrace, and on my system, I have the same issue... I will try to generate a new stacktrace for you..
the corresponding line is " if (g < 0 || g >= XkbKeyNumGroups (drawing->xkb, keycode))", if drawing is not a correct GkbdKeyboardDrawing it can crash
(In reply to comment #4) > (In reply to comment #3) > > I just tried your config - I setup the keyboard to be MS Natural Pro USB - and > > I can add layouts without any trouble. Which means I cannot reproduce your > > problem:( > > Do you have a 32bit or 64bit system? > > > BTW in my code the line 872 is not in draw_key but in draw_key_label - and I > > cannot see why would anything on that line could cause the crash. > > I did not generate that stacktrace, and on my system, I have the same issue... > I will try to generate a new stacktrace for you.. > Interestingly enough, that stack trace is "sort of" correct. The last line of draw_key is draw_key_label, so the compiler has optimised out the call, and replaced it with a jump to draw_key_label, so that stack frame has disappeared. The problem is somewhere on the path: ((drawing->xkb)->map)->key_sym_map[keycode].group_info As this is what is calculated during the call on line 872. Unfortunately, since the build is optimised, I cannot tell what keycode actually is, however: (gdb) print ((drawing->xkb)->map)->key_sym_map $14 = (XkbSymMapPtr) 0x946fc0 So I suspect that the keycode is a shade wrong. A bit more playing around in draw_key, and I see that draw_key is (at a certain point) called with key: (gdb) print *key $25 = {type = GKBD_KEYBOARD_DRAWING_ITEM_TYPE_KEY, origin_x = 317, origin_y = 483, angle = 100, priority = 131072, xkbkey = 0x9499d0, pressed = 0, keycode = 4294967295} Note, that that keycode is very, very bad :-) I hope that this helps... if you need more information, please let me know.
(In reply to comment #6) > The problem is somewhere on the path: > > ((drawing->xkb)->map)->key_sym_map[keycode].group_info > > As this is what is calculated during the call on line 872. I should point out that XkbKeyNumGroups is a macro, that calls another macro, that is why the above path is generated. http://lxr.freedesktop.org/source/proto/KB/XKBstr.h#L441 which in turn uses this macro: http://lxr.freedesktop.org/source/proto/KB/XKBstr.h#L335
I run it in 32bit environment. Your explanation really make sense - this keycode looks highly invalid. The question is where in the stack you managed to pick it... Could you please add some printf statements and find where this keycode came from?
(In reply to comment #8) > I run it in 32bit environment. > > Your explanation really make sense - this keycode looks highly invalid. The > question is where in the stack you managed to pick it... Could you please add > some printf statements and find where this keycode came from? I will try to see what I can do, but unfortunately, the only machine that I can do this on (at the moment) is at work, which cuts down the time I can spend playing to find the issue...
I found one possible reason for it. Could you please take libgnomekbd from SVN and see whether you still see that message and the crash?
I just pulled the patch from http://svn.gnome.org/viewcvs/libgnomekbd/trunk/libgnomekbd/gkbd-keyboard-drawing.c?r1=102&r2=101&pathrev=102 and applied it to the debian 2.18.1 package, as that would appear to be the only substantive difference, however I have some bad news :-)
+ Trace 130847
(gdb) list 545 pkey++; 546 } 547 548 palias = drawing->xkb->names->key_aliases; 549 for (i = drawing->xkb->names->num_key_aliases; --i >= 0;) { 550 if (palias->alias[0] == key_name[0] 551 && palias->alias[1] == key_name[1] 552 && palias->alias[2] == key_name[2] 553 && palias->alias[3] == key_name[3]) 554 return find_keycode (drawing, palias->real); (gdb) display palias 3: palias = (XkbKeyAliasPtr) 0x955000 (gdb) display key_name 4: key_name = (gchar *) 0x949e80 "AE00\n" (gdb) display palias->alias Disabling display 5 to avoid infinite recursion. 5: palias->alias = Cannot access memory at address 0x955004 (gdb) print i $2 = 8 hope this helps some.
OK. Some more playing around, and I see the first bug :-) guint can never not be >= 0, so the for loop is unterminated. I have changed it to read: for (i = drawing->xkb->names->num_key_aliases; i > 0; --i) { Now I get further... but not a lot further ;-) It still dies in exactly the same place, with the caveat that this time it is line 887, and not 872 due to the above patches line offsets.
What this is showing is that find_keycode is definitely not finding the keycode, for whatever reason, and so at a certain point, it all just blows up. The error code should probably be checked for and those keys not shown. Also, line 1511 should have a %u as it's last printf escape code. (This the debuig line for printing out the "initing key" string) With that fix in place then I get the following debug: initing key 0, shape: 0x9489d0(0x9489d0 + 0), code: 4294967295
Well spotted about guint. Could you please change guint to gint - and revert to the original (but patched) code? Also, could you please change #define noKBDRAW_DEBUG to #define KBDRAW_DEBUG, rebuild and attach the output here?
(In reply to comment #14) > Well spotted about guint. Could you please change guint to gint - and revert to > the original (but patched) code? > > Also, could you please change #define noKBDRAW_DEBUG to #define KBDRAW_DEBUG, > rebuild and attach the output here? I have to say that the mixing between signed and unsigned that happens all through out the code disturbs me :-) Anyway, I have changed i to be gint (which then gets implicitly cast to guint when we return), and I get the same results as before (which is to be expected) Anyway, attaching the output.
Created attachment 87125 [details] output when debug is enabled.
> I have to say that the mixing between signed and unsigned that happens all > through out the code disturbs me :-) In this particular case changing "guint" to "gint" is a quick hack which I'll fix. But if you see other places - please let me know. > Anyway, I have changed i to be gint (which then gets implicitly cast to guint > when we return), and I get the same results as before (which is to be expected) > > Anyway, attaching the output. Well, this output is really interesting. It seems it cannot resolve the name AE00 to keycode. I'll try to find why.
It seems I know why. Because it is missing from keycodes... It is actually NOTGNOME, with all fairness. So I'll fix the origin of the problem (in xkeyboard-config) first, then make libgnomekbd more robust. Thanks for spotting it!
geometry/microsoft refers to AE00 which is not defined in keycodes/pc. Once I changed AE00 to TLDE - there is no error any more. Could you please check? I'll commit it to xkeyboard-config.
Well... gnome-keyboard-properties doesn't die, however the X server freezes and takes 100% of CPU. On my system geometry/hp,pc,thinkpad also refer to AE00.
I'll check other geometries as well. Could you please try test/gkbd-keyboard-drawing-test from libgnomekbd? It has some command line options as well...
Created attachment 93667 [details] [review] proposed patch for the 429907 bug I've located the bug. The crash happens in function draw_key_label in call XkbKeyNumGroups when drawing a key. This is Xlib fault actually. If the keycode is -1 - segfault. The keycode -1 is returned from the find_keycode function. The patch is a dirty fix. The unkeycoded keys are not drawn at all(not added to the keys list), but at least there's no crash.
Sasha, I might agree with the second part of your patch - but the first part is somewhat unclear. How happened draw_key_label got keycode -1? Could you provide the stack trace explaining it?
Sergey, the patch is actually paranoid and even more the parts are not really connected. First check is there simply to avoid crash if for some reason the key with -1 keycode was created. Which actually should never happen with the second part applied. You can leave just one of them and this should work. The only problem is that if you have the first change - you'll draw an empty and unrecognized key(which is not good). If the second - the key'll be missed(which is bad). In my case, with both applied I don't have a tilde(that misfamous AE00 on MS natural kb) key. As I've said, my patch is a dirty fix. As for the -1. Check the find_keycode function. If it fails finding the key mapping it returns -1, indicating error. And in my case it happens with a tilde. That's it.
The missing key with keycode -1 is ok. It is not bad - it is just broken xkb config (which libgnomekbd does not have to support - it just should not crash). Ok, second part committed. Thanks.
Sasha, BTW I do not understand how happend you got keycode -1. Could you please do "xkbcomp :0 -out out.xkb" and attach your out.xkb?
Created attachment 93811 [details] xkbcomp output xkbcomp output. the crashing key is AE00, which has simply no keycode mapping in X configuration. but the key's there and it's TLDE. so technically the bug is X configuration problem and xlib reaction to -1... and our usage of error code as a keymap ;-=--) unfortunately it showed up that late in gnome. fortunately there's a light in the end of da tunnel.
I see. You're not using the latest xkeyboard-config. Now AE00 is an alias to TLDE.
*** Bug 404107 has been marked as a duplicate of this bug. ***
*** Bug 492341 has been marked as a duplicate of this bug. ***