Handle asyncronous X11 errors
Errors for requests sent via Xlib that expect a reply are handled via XSetErrorHandler(), which sets up a callback function that Xlib calls. Errors for requests that do not expect a reply or for errors caused via unchecked XCB requests show up as events of type 0 in the event handling function. Before this commit, errors were ignored here. This commit changes the code so that the errors are printed instead. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
3ed73b1f8e
commit
00ae9718ee
|
@ -2496,21 +2496,21 @@ root_damaged(session_t *ps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Xlib error handler function.
|
* X11 error handler function.
|
||||||
*/
|
*/
|
||||||
static int
|
static void
|
||||||
xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
xerror_common(unsigned long serial, uint8_t major, uint8_t minor, uint8_t error_code) {
|
||||||
session_t * const ps = ps_g;
|
session_t * const ps = ps_g;
|
||||||
|
|
||||||
int o = 0;
|
int o = 0;
|
||||||
const char *name = "Unknown";
|
const char *name = "Unknown";
|
||||||
|
|
||||||
if (should_ignore(ps, ev->serial)) {
|
if (should_ignore(ps, serial)) {
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev->request_code == ps->composite_opcode
|
if (major == ps->composite_opcode
|
||||||
&& ev->minor_code == XCB_COMPOSITE_REDIRECT_SUBWINDOWS) {
|
&& minor == XCB_COMPOSITE_REDIRECT_SUBWINDOWS) {
|
||||||
fprintf(stderr, "Another composite manager is already running "
|
fprintf(stderr, "Another composite manager is already running "
|
||||||
"(and does not handle _NET_WM_CM_Sn correctly)\n");
|
"(and does not handle _NET_WM_CM_Sn correctly)\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -2518,17 +2518,17 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
||||||
|
|
||||||
#define CASESTRRET2(s) case s: name = #s; break
|
#define CASESTRRET2(s) case s: name = #s; break
|
||||||
|
|
||||||
o = ev->error_code - ps->xfixes_error;
|
o = error_code - ps->xfixes_error;
|
||||||
switch (o) {
|
switch (o) {
|
||||||
CASESTRRET2(BadRegion);
|
CASESTRRET2(BadRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
o = ev->error_code - ps->damage_error;
|
o = error_code - ps->damage_error;
|
||||||
switch (o) {
|
switch (o) {
|
||||||
CASESTRRET2(XCB_DAMAGE_BAD_DAMAGE);
|
CASESTRRET2(XCB_DAMAGE_BAD_DAMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
o = ev->error_code - ps->render_error;
|
o = error_code - ps->render_error;
|
||||||
switch (o) {
|
switch (o) {
|
||||||
CASESTRRET2(XCB_RENDER_PICT_FORMAT);
|
CASESTRRET2(XCB_RENDER_PICT_FORMAT);
|
||||||
CASESTRRET2(XCB_RENDER_PICTURE);
|
CASESTRRET2(XCB_RENDER_PICTURE);
|
||||||
|
@ -2539,7 +2539,7 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
||||||
|
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
if (ps->glx_exists) {
|
if (ps->glx_exists) {
|
||||||
o = ev->error_code - ps->glx_error;
|
o = error_code - ps->glx_error;
|
||||||
switch (o) {
|
switch (o) {
|
||||||
CASESTRRET2(GLX_BAD_SCREEN);
|
CASESTRRET2(GLX_BAD_SCREEN);
|
||||||
CASESTRRET2(GLX_BAD_ATTRIBUTE);
|
CASESTRRET2(GLX_BAD_ATTRIBUTE);
|
||||||
|
@ -2554,7 +2554,7 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
||||||
|
|
||||||
#ifdef CONFIG_XSYNC
|
#ifdef CONFIG_XSYNC
|
||||||
if (ps->xsync_exists) {
|
if (ps->xsync_exists) {
|
||||||
o = ev->error_code - ps->xsync_error;
|
o = error_code - ps->xsync_error;
|
||||||
switch (o) {
|
switch (o) {
|
||||||
CASESTRRET2(XSyncBadCounter);
|
CASESTRRET2(XSyncBadCounter);
|
||||||
CASESTRRET2(XSyncBadAlarm);
|
CASESTRRET2(XSyncBadAlarm);
|
||||||
|
@ -2563,7 +2563,7 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (ev->error_code) {
|
switch (error_code) {
|
||||||
CASESTRRET2(BadAccess);
|
CASESTRRET2(BadAccess);
|
||||||
CASESTRRET2(BadAlloc);
|
CASESTRRET2(BadAlloc);
|
||||||
CASESTRRET2(BadAtom);
|
CASESTRRET2(BadAtom);
|
||||||
|
@ -2588,17 +2588,32 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
||||||
print_timestamp(ps);
|
print_timestamp(ps);
|
||||||
{
|
{
|
||||||
char buf[BUF_LEN] = "";
|
char buf[BUF_LEN] = "";
|
||||||
XGetErrorText(ps->dpy, ev->error_code, buf, BUF_LEN);
|
XGetErrorText(ps->dpy, error_code, buf, BUF_LEN);
|
||||||
printf("error %4d %-12s request %4d minor %4d serial %6lu: \"%s\"\n",
|
printf("error %4d %-12s request %4d minor %4d serial %6lu: \"%s\"\n",
|
||||||
ev->error_code, name, ev->request_code,
|
error_code, name, major,
|
||||||
ev->minor_code, ev->serial, buf);
|
minor, serial, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// print_backtrace();
|
// print_backtrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Xlib error handler function.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
||||||
|
xerror_common(ev->serial, ev->request_code, ev->minor_code, ev->error_code);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XCB error handler function.
|
||||||
|
*/
|
||||||
|
inline static void
|
||||||
|
ev_xcb_error(session_t __attribute__((unused)) *ps, xcb_generic_error_t *err) {
|
||||||
|
xerror_common(err->sequence, err->major_code, err->minor_code, err->error_code);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
expose_root(session_t *ps, XRectangle *rects, int nrects) {
|
expose_root(session_t *ps, XRectangle *rects, int nrects) {
|
||||||
free_all_damage_last(ps);
|
free_all_damage_last(ps);
|
||||||
|
@ -3268,6 +3283,9 @@ ev_handle(session_t *ps, xcb_generic_event_t *ev) {
|
||||||
case SelectionClear:
|
case SelectionClear:
|
||||||
ev_selection_clear(ps, (xcb_selection_clear_event_t *)ev);
|
ev_selection_clear(ps, (xcb_selection_clear_event_t *)ev);
|
||||||
break;
|
break;
|
||||||
|
case 0:
|
||||||
|
ev_xcb_error(ps, (xcb_generic_error_t *)ev);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (ps->shape_exists && ev->response_type == ps->shape_event) {
|
if (ps->shape_exists && ev->response_type == ps->shape_event) {
|
||||||
ev_shape_notify(ps, (xcb_shape_notify_event_t *) ev);
|
ev_shape_notify(ps, (xcb_shape_notify_event_t *) ev);
|
||||||
|
|
Loading…
Reference in New Issue