Description of Problem: When changing app theme in some CJK locales nautilus crashes (restarts). Version-Release number of selected component (if applicable): 2.0.4-3 How Reproducible: Every time. Steps to Reproduce: 1. Start a gnome session in Japanese say. 2. run gnome-theme-properties 3. Change Application theme. Actual Results: Nautilus restarts, sometimes taking all apps (wm?) with it. Expected Results: Theme should just change without nautilus dying. Additional Information: The problem doesn't seem to occur with Western locales.
Probably easy to diagnose if we get a backtrace with symbols.
This isn't just nautilus, I have also reproduced now with gnome-terminal and gnome-panel. I get gtkstyle.c: line 631 (gtk_style_finalize): assertion style->attach_count == 0 failed followed by a BadAtom X error that actually results in the app exiting. The warning and X error only happen for gnome-terminal not for nautilus/panel, I don't know what's wrong with them. Most likely a bug in Bluecurve theme engine. msf also just saw a bug where submenus were huge (larger than the screen).
The reason this apparently happens in CJK is that the X error is in XimThaiCloseIM() (XGetWindowProperty() call in there). Of course the theme shouldn't be able to affect the IM, so... maybe it isn't a theme bug.
With symbols it's fairly easy to find what goes wrong locally; a _GTK_READ_RCFILES message gets to Xlib, imTrX.c:361 marked below. Looking elsewhere in imTrX.c, _CheckCMEvent() should have filtered out this event (and spec->improtocolid and spec->immoredataid are valid and correct). However there is a codepath in _XimXRead() that does not go through CheckCMEvent, namely where spec->ev is preexisting. This is indeed what's in the backtrace, XFilterEvent()->XimXFilterWaitEvent()->XimFilterWaitEvent()->XimReadData()-> XimXRead()->XimXGetReadData()->boom. I believe the right fix is that XimXFilterWaitEvent() should contain the equivalent filter to _CheckCMEvent() to avoid reacting to just any client message event. So moving to Xlib. I don't know why this just now started happening. Private Bool _XimXGetReadData(im, buf, buf_len, ret_len, event) Xim im; char *buf; int buf_len; int *ret_len; XEvent *event; { char *data; int len; char tmp_buf[XIM_CM_DATA_SIZE]; XSpecRec *spec = (XSpecRec *)im->private.proto.spec; unsigned long length; Atom prop; int return_code; Atom type_ret; int format_ret; unsigned long nitems; unsigned long bytes_after_ret; unsigned char *prop_ret; if ((event->type == ClientMessage) && (event->xclient.format == 8)) { data = event->xclient.data.b; if (buf_len >= XIM_CM_DATA_SIZE) { (void)memcpy(buf, data, XIM_CM_DATA_SIZE); *ret_len = XIM_CM_DATA_SIZE; } else { (void)memcpy(buf, data, buf_len); len = XIM_CM_DATA_SIZE - buf_len; (void)memcpy(tmp_buf, &data[buf_len], len); bzero(data, XIM_CM_DATA_SIZE); (void)memcpy(data, tmp_buf, len); XPutBackEvent(im->core.display, event); *ret_len = buf_len; } } else if ((event->type == ClientMessage) && (event->xclient.format == 32)) { length = (unsigned long)event->xclient.data.l[0]; prop = (Atom)event->xclient.data.l[1]; ***** Here is line 361: ***** note event->xclient.message_type is _GTK_READ_RCFILES ***** event->xclient.data.l[1] is just None, thus BadAtom return_code = XGetWindowProperty(im->core.display, spec->lib_connect_wid, prop, 0L, (long)((length + 3)/ 4), True, AnyPropertyType, &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret); if (return_code != Success || format_ret == 0 || nitems == 0) { if (return_code == Success) XFree(prop_ret); return False; } if (buf_len >= length) { (void)memcpy(buf, prop_ret, (int)nitems); *ret_len = (int)nitems; if (bytes_after_ret > 0) { XGetWindowProperty(im->core.display, spec->lib_connect_wid, prop, 0L, ((length + bytes_after_ret + 3)/ 4), True, AnyPropertyType, &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret); XChangeProperty(im->core.display, spec->lib_connect_wid, prop, XA_STRING, 8, PropModePrepend, &prop_ret[length], (nitems - length)); } } else { (void)memcpy(buf, prop_ret, buf_len); *ret_len = buf_len; len = nitems - buf_len; if (bytes_after_ret > 0) { XFree(prop_ret); XGetWindowProperty(im->core.display, spec->lib_connect_wid, prop, 0L, ((length + bytes_after_ret + 3)/ 4), True, AnyPropertyType, &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret); } XChangeProperty(im->core.display, spec->lib_connect_wid, prop, XA_STRING, 8, PropModePrepend, &prop_ret[buf_len], len); event->xclient.data.l[0] = (long)len; event->xclient.data.l[1] = (long)prop; XPutBackEvent(im->core.display, event); } XFree(prop_ret); } else if (event->type == PropertyNotify) { prop = event->xproperty.atom; return_code = XGetWindowProperty(im->core.display, spec->lib_connect_wid, prop, 0L, 1000000L, True, AnyPropertyType, &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret); if (return_code != Success || format_ret == 0 || nitems == 0) { if (return_code == Success) XFree(prop_ret); return False; } if (buf_len >= nitems) { (void)memcpy(buf, prop_ret, (int)nitems); *ret_len = (int)nitems; } else { (void)memcpy(buf, prop_ret, buf_len); *ret_len = buf_len; len = nitems - buf_len; XChangeProperty(im->core.display, spec->lib_connect_wid, prop, XA_STRING, 8, PropModePrepend, &prop_ret[buf_len], len); } XFree(prop_ret); } return True; }
Here is all the gdb stuff: (gdb) run Starting program: /usr/bin/testgtk Breakpoint 1, 0x08070276 in main () (gdb) break gdk_x_error Breakpoint 2 at 0x40083e96 (gdb) cont Continuing. ** (testgtk:30154): CRITICAL **: file pango-context.c: line 310 (pango_context_get_language): assertion `context != NULL' failed Breakpoint 2, 0x40083e96 in gdk_x_error () from /usr/lib/libgdk-x11-2.0.so.0 (gdb) bt #0 0x40083e96 in gdk_x_error () from /usr/lib/libgdk-x11-2.0.so.0 #1 0x40383aee in _XError (dpy=0x8082958, rep=0xbfffebe0) at XlibInt.c:2886 #2 0x40381b74 in _XReply (dpy=0x8082958, rep=0xbfffebe0, extra=0, discard=0) at XlibInt.c:1775 #3 0x40365607 in XGetWindowProperty (dpy=0x8082958, w=33554941, property=0, offset=0, length=0, delete=1, req_type=0, actual_type=0xbfffec5c, actual_format=0xbfffec58, nitems=0xbfffec54, bytesafter=0xbfffec50, prop=0xbfffec4c) at GetProp.c:61 #4 0x40abef21 in _XimXGetReadData (im=0x81a2270, buf=0xbfffede0 "", buf_len=2048, ret_len=0xbfffecdc, event=0xbffff680) at imTrX.c:361 #5 0x40abf310 in _XimXRead (im=0x81a2270, recv_buf=0xbfffede0 "", buf_len=2048, ret_len=0xbfffed90) at imTrX.c:474 #6 0x40abf742 in _XimReadData (im=0x81a2270, len=0xbffff5ee, buf=0xbfffede0 "", buf_size=2048) at imTransR.c:158 #7 0x40abfa96 in _XimFilterWaitEvent (im=0x81a2270) at imTransR.c:284 #8 0x40abe787 in _XimXFilterWaitEvent (d=0x8082958, w=33554941, ev=0xbffff680, arg=0x81a2270 "�021�愡\a\bHq \bX)\b\b") at imTrX.c:111 #9 0x403a0daa in XFilterEvent (ev=0xbffff680, window=0) at FilterEv.c:91 #10 0x40079c91 in _gdk_events_queue () from /usr/lib/libgdk-x11-2.0.so.0 #11 0x40079eb4 in gdk_event_dispatch () from /usr/lib/libgdk-x11-2.0.so.0 #12 0x4055df65 in g_main_dispatch () from /usr/lib/libglib-2.0.so.0 #13 0x4055ef98 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0 #14 0x4055f2ad in g_main_context_iterate () from /usr/lib/libglib-2.0.so.0 ---Type <return> to continue, or q <return> to quit--- #15 0x4055fa1f in g_main_loop_run () from /usr/lib/libglib-2.0.so.0 #16 0x4017539f in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0 #17 0x0807041c in main () #18 0x420155c4 in __libc_start_main () from /lib/i686/libc.so.6 (gdb) up 2 #2 0x40381b74 in _XReply (dpy=0x8082958, rep=0xbfffebe0, extra=0, discard=0) at XlibInt.c:1775 1775 _XError(dpy, err); (gdb) up #3 0x40365607 in XGetWindowProperty (dpy=0x8082958, w=33554941, property=0, offset=0, length=0, delete=1, req_type=0, actual_type=0xbfffec5c, actual_format=0xbfffec58, nitems=0xbfffec54, bytesafter=0xbfffec50, prop=0xbfffec4c) at GetProp.c:61 61 if (!_XReply (dpy, (xReply *) &reply, 0, xFalse)) { (gdb) up #4 0x40abef21 in _XimXGetReadData (im=0x81a2270, buf=0xbfffede0 "", buf_len=2048, ret_len=0xbfffecdc, event=0xbffff680) at imTrX.c:361 361 return_code = XGetWindowProperty(im->core.display, (gdb) list 356 } 357 } else if ((event->type == ClientMessage) 358 && (event->xclient.format == 32)) { 359 length = (unsigned long)event->xclient.data.l[0]; 360 prop = (Atom)event->xclient.data.l[1]; 361 return_code = XGetWindowProperty(im->core.display, 362 spec->lib_connect_wid, prop, 0L, 363 (long)((length + 3)/ 4), True, AnyPropertyType, 364 &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret); 365 if (return_code != Success || format_ret == 0 || nitems == 0) { (gdb) p prop $1 = 0 (gdb) e Ambiguous command "e": echo, en, enable, end, exec-file. (gdb) p event->xclient.data.l[1] $2 = 0 (gdb) p event->xclient $3 = {type = 33, serial = 25507, send_event = 1, display = 0x8082958, window = 33554941, message_type = 459, format = 32, data = { b = '\0' <repeats 19 times>, s = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, l = {0, 0, 0, 0, 0}}} (gdb) p XAtomName(event->xclient.message_type) No symbol "XAtomName" in current context. (gdb) p XGetAtomName(event->xclient.message_type) too few arguments in function call (gdb) p XGetAtomName(display, event->xclient.message_type) No symbol "display" in current context. (gdb) p XGetAtomName(im->core.display, event->xclient.message_type) $4 = 0x821b0f0 "_GTK_READ_RCFILES" (gdb) frame #4 0x40abef21 in _XimXGetReadData (im=0x81a2270, buf=0xbfffede0 "", buf_len=2048, ret_len=0xbfffecdc, event=0xbffff680) at imTrX.c:361 361 return_code = XGetWindowProperty(im->core.display, (gdb) p spec $5 = (struct _XSpecRec *) 0x81a0ce0 (gdb) p spec->improtocolid $6 = 396 (gdb) p XGetAtomName (im->core.display, spec->improtocolid) $7 = 0x8228428 "_XIM_PROTOCOL" (gdb) p XGetAtomName (im->core.display, spec->immoredataid) $8 = 0x8228ad0 "_XIM_MOREDATA" (gdb) p event->type $9 = 33
Created attachment 73664 [details] proposed fix
mharris do you want someone else to build with that patch or are you on it?
Improved a lot with the patch, but still have problems: 1 Everytime I changed Theme or Window Border, daemon in charge of drawing "Root's Home", "Start Here", "Trash" icons will hang(not crash). 2 Some appliactions like gnome-terminal is fine with theme or Window Border changing. Some applications will hang like xterm. 3 Nautilus seems fine with theme changing, but some time hang with Window Border style changing, after 10 or 20 senconds it will restart.
Nautilus is what is drawing the desktop icons. Does it hang on theme change? If so I'd like a backtrace of where it hangs (for all threads).
yshao can you get a backtrace of some of these, so we can tell if it's the same bug or some other problems?
Created attachment 73760 [details] better patch (return False)
OK let's try this patch... I'll test it this afternoon also.
The second patch seems to resolve the problem entirely on my system.
Yeah, the second patch is cool, fixed all the probelms! Thanks!
Closing as fixed in Rawhide by Havoc's patch.