Glynn Clements wrote:
> >> XEmacs 21.4-14 hangs when editres client asks
'Select widget in
> >> client'. XEmacs 21.5 does not hang.
> >> XEmacs prints in the console:
> >> xemacs: X Error of failed request: BadWindow (invalid Window
> >> parameter)
>
> Glynn> I get the same result here (BadWindow error for
> Glynn> X_GetWindowAttributes, XEmacs hangs).
>
> Now this is interesting. Glynn, so you think there's a chance that
> this is a repeatable instance of whatever it is that causes the
> intermittent BadWindow bugs we see?
My suspicion is that there is a problem with error handling.
E.g. in this instance, XGetWindowAttributes never returns. It's
blocking in _XReply(), presumably waiting for the X server to send it
the window's attributes. But XGetWindowAttributes() does appear to
allow for _XReply() failing, and _XReply() handles X_Error packets.
> What options do we have? Our own error handler?
We already have that. The default X error handler just prints the
message then calls exit(). Ours doesn't do appear to do much more, but
it uses stderr_out, and I'm wondering if that is doing something
illegal (e.g. inadvertantly calling X functions).
More evidence in support of that suspicion: if I run XEmacs under gdb,
and make x_error_handler() return immediately, the problem vanishes.
Single stepping through various bits of code which I don't pretend to
understand, I managed to end up here:
event-Xt.c:
2876 XEventsQueued (display, QueuedAfterReading);
2877 queued = XCheckIfEvent (display, &event,
2878 quit_char_predicate,
2879 (char *) &critical_quit);
#0 emacs_Xt_quit_p () at event-Xt.c:2876
#1 0x08119632 in event_stream_quit_p () at event-stream.c:596
#2 0x081c230a in check_quit () at signal.c:513
#3 0x080cd55e in unbind_to_hairy (count=7) at eval.c:4973
#4 0x080ccfb2 in unbind_to (count=7, value=
{gu = {type = Lisp_Type_Record, val = 34234677}, s = {bits = 0, val = 68469354}, u =
{bits = 0, val = 68469354}, ui = 136938708, i = 136938708, v = 0x82984d4, cv = 0x82984d4})
at eval.c:4959
#5 0x08091cb6 in dfc_convert_to_external_format (source_type=DFC_TYPE_DATA,
source=0xbfff96d8, coding_system=
{gu = {type = Lisp_Type_Record, val = 34371126}, s = {bits = 0, val = 68742252}, u =
{bits = 0, val = 68742252}, ui = 137484504, i = 137484504, v = 0x831d8d8, cv = 0x831d8d8},
sink_type=DFC_TYPE_DATA, sink=0xbfff96d0)
at buffer.c:1948
#6 0x0818c112 in std_handle_out_va (stream=0x405699c0,
fmt=0x82410e5 "\n%s: ", args=0xbfffb744) at print.c:186
#7 0x0818c179 in stderr_out (fmt=0x82410e5 "\n%s: ") at print.c:208
#8 0x081de990 in x_error_handler (disp=0x865e790, event=0xbfffb770)
at device-x.c:1060
#9 0x40300801 in _XError (dpy=0x865e790, rep=0xbfffb890) at XlibInt.c:2898
(More stack frames follow...)
So, x_error_handler ends up checking for quit, which involves calling
X functions, which isn't permitted inside an X error handler.
Note: the entire reason why x_error_handler() calls stderr_out() is so
that it can prefix the default Xmu error message with the program
name:
stderr_out ("\n%s: ",
(STRINGP (Vinvocation_name)
? (char *) XSTRING_DATA (Vinvocation_name)
: "xemacs"));
XmuPrintDefaultErrorMessage (disp, event, stderr);
If I disable the call to stderr_out, the problem goes away. I still
see the BadWindow error, but it doesn't cause XEmacs to hang.
--
Glynn Clements <glynn.clements(a)virgin.net>
--- src/device-x.c~ Wed Aug 21 23:59:00 2002
+++ src/device-x.c Fri Jan 30 18:21:45 2004
@@ -1057,10 +1057,14 @@
}
#endif /* EXTERNAL_WIDGET */
+#if 0
+ /* This ends up calling X, which isn't allowed in an X error handler
+ */
stderr_out ("\n%s: ",
(STRINGP (Vinvocation_name)
? (char *) XSTRING_DATA (Vinvocation_name)
: "xemacs"));
+#endif
XmuPrintDefaultErrorMessage (disp, event, stderr);
}
return 0;