Bug 72236 - applications crashing every time when changing app theme in CJK locale
Summary: applications crashing every time when changing app theme in CJK locale
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Red Hat Public Beta
Classification: Retired
Component: XFree86
Version: null
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Mike A. Harris
QA Contact: Jay Turner
URL:
Whiteboard:
Depends On:
Blocks: 67217
TreeView+ depends on / blocked
 
Reported: 2002-08-22 09:15 UTC by Jens Petersen
Modified: 2015-01-07 23:59 UTC (History)
7 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2002-08-29 23:54:20 UTC
Embargoed:


Attachments (Terms of Use)
proposed fix (934 bytes, patch)
2002-08-29 02:19 UTC, Havoc Pennington
no flags Details | Diff
better patch (return False) (930 bytes, patch)
2002-08-29 17:00 UTC, Havoc Pennington
no flags Details | Diff

Description Jens Petersen 2002-08-22 09:15:38 UTC
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.

Comment 1 Havoc Pennington 2002-08-23 01:21:33 UTC
Probably easy to diagnose if we get a backtrace with symbols.

Comment 2 Havoc Pennington 2002-08-23 20:01:34 UTC
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).


Comment 3 Havoc Pennington 2002-08-23 20:04:25 UTC
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.

Comment 4 Havoc Pennington 2002-08-24 22:18:21 UTC
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;
}


Comment 5 Havoc Pennington 2002-08-24 22:23:17 UTC
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


Comment 6 Havoc Pennington 2002-08-29 02:19:40 UTC
Created attachment 73664 [details]
proposed fix

Comment 7 Havoc Pennington 2002-08-29 02:20:40 UTC
mharris do you want someone else to build with that patch or are you on it?

Comment 8 Yu Shao 2002-08-29 08:15:08 UTC
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.

Comment 9 Alexander Larsson 2002-08-29 09:15:11 UTC
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).

Comment 10 Havoc Pennington 2002-08-29 14:22:54 UTC
yshao can you get a backtrace of some of these, so we can tell if it's the same
bug or some other problems?

Comment 11 Havoc Pennington 2002-08-29 17:00:55 UTC
Created attachment 73760 [details]
better patch (return False)

Comment 12 Havoc Pennington 2002-08-29 17:01:25 UTC
OK let's try this patch... I'll test it this afternoon also.

Comment 13 Havoc Pennington 2002-08-29 18:49:19 UTC
The second patch seems to resolve the problem entirely on my system.

Comment 14 Yu Shao 2002-08-29 23:54:10 UTC
Yeah, the second patch is cool, fixed all the probelms! Thanks!

Comment 15 Mike A. Harris 2002-08-30 15:43:18 UTC
Closing as fixed in Rawhide by Havoc's patch.


Note You need to log in before you can comment on or make changes to this bug.