backend/x11: log errors

Register an X11 error handler, and optionally use xcb-errors to print a
detailed message.
This commit is contained in:
Simon Ser 2020-11-18 19:06:45 +01:00
parent 262740bc9a
commit 52805feae9
2 changed files with 66 additions and 1 deletions

View file

@ -38,6 +38,8 @@ struct wlr_x11_output *get_x11_output_from_window_id(
return NULL; return NULL;
} }
static void handle_x11_error(struct wlr_x11_backend *x11, xcb_value_error_t *ev);
static void handle_x11_event(struct wlr_x11_backend *x11, static void handle_x11_event(struct wlr_x11_backend *x11,
xcb_generic_event_t *event) { xcb_generic_event_t *event) {
switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) {
@ -76,6 +78,12 @@ static void handle_x11_event(struct wlr_x11_backend *x11,
if (ev->extension == x11->xinput_opcode) { if (ev->extension == x11->xinput_opcode) {
handle_x11_xinput_event(x11, ev); handle_x11_xinput_event(x11, ev);
} }
break;
}
case 0: {
xcb_value_error_t *ev = (xcb_value_error_t *)event;
handle_x11_error(x11, ev);
break;
} }
} }
} }
@ -140,6 +148,10 @@ static void backend_destroy(struct wlr_backend *backend) {
wlr_renderer_destroy(x11->renderer); wlr_renderer_destroy(x11->renderer);
wlr_egl_finish(&x11->egl); wlr_egl_finish(&x11->egl);
#if WLR_HAS_XCB_ERRORS
xcb_errors_context_free(x11->errors_context);
#endif
if (x11->xlib_conn) { if (x11->xlib_conn) {
XCloseDisplay(x11->xlib_conn); XCloseDisplay(x11->xlib_conn);
} }
@ -296,6 +308,13 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
goto error_event; goto error_event;
} }
#if WLR_HAS_XCB_ERRORS
if (xcb_errors_context_new(x11->xcb, &x11->errors_context) != 0) {
wlr_log(WLR_ERROR, "Failed to create error context");
return false;
}
#endif
wlr_input_device_init(&x11->keyboard_dev, WLR_INPUT_DEVICE_KEYBOARD, wlr_input_device_init(&x11->keyboard_dev, WLR_INPUT_DEVICE_KEYBOARD,
&input_device_impl, "X11 keyboard", 0, 0); &input_device_impl, "X11 keyboard", 0, 0);
wlr_keyboard_init(&x11->keyboard, &keyboard_impl); wlr_keyboard_init(&x11->keyboard, &keyboard_impl);
@ -314,3 +333,40 @@ error_x11:
free(x11); free(x11);
return NULL; return NULL;
} }
static void handle_x11_error(struct wlr_x11_backend *x11, xcb_value_error_t *ev) {
#if WLR_HAS_XCB_ERRORS
const char *major_name = xcb_errors_get_name_for_major_code(
x11->errors_context, ev->major_opcode);
if (!major_name) {
wlr_log(WLR_DEBUG, "X11 error happened, but could not get major name");
goto log_raw;
}
const char *minor_name = xcb_errors_get_name_for_minor_code(
x11->errors_context, ev->major_opcode, ev->minor_opcode);
const char *extension;
const char *error_name = xcb_errors_get_name_for_error(x11->errors_context,
ev->error_code, &extension);
if (!error_name) {
wlr_log(WLR_DEBUG, "X11 error happened, but could not get error name");
goto log_raw;
}
wlr_log(WLR_ERROR, "X11 error: op %s (%s), code %s (%s), "
"sequence %"PRIu16", value %"PRIu32,
major_name, minor_name ? minor_name : "no minor",
error_name, extension ? extension : "no extension",
ev->sequence, ev->bad_value);
return;
log_raw:
#endif
wlr_log(WLR_ERROR, "X11 error: op %"PRIu8":%"PRIu16", code %"PRIu8", "
"sequence %"PRIu16", value %"PRIu32,
ev->major_opcode, ev->minor_opcode, ev->error_code,
ev->sequence, ev->bad_value);
}

View file

@ -1,14 +1,19 @@
#ifndef BACKEND_X11_H #ifndef BACKEND_X11_H
#define BACKEND_X11_H #define BACKEND_X11_H
#include <wlr/config.h>
#include <stdbool.h> #include <stdbool.h>
#include <X11/Xlib-xcb.h> #include <X11/Xlib-xcb.h>
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#if WLR_HAS_XCB_ERRORS
#include <xcb/xcb_errors.h>
#endif
#include <wlr/backend/x11.h> #include <wlr/backend/x11.h>
#include <wlr/config.h>
#include <wlr/interfaces/wlr_input_device.h> #include <wlr/interfaces/wlr_input_device.h>
#include <wlr/interfaces/wlr_keyboard.h> #include <wlr/interfaces/wlr_keyboard.h>
#include <wlr/interfaces/wlr_output.h> #include <wlr/interfaces/wlr_output.h>
@ -81,6 +86,10 @@ struct wlr_x11_backend {
// The time we last received an event // The time we last received an event
xcb_timestamp_t time; xcb_timestamp_t time;
#if WLR_HAS_XCB_ERRORS
xcb_errors_context_t *errors_context;
#endif
uint8_t xinput_opcode; uint8_t xinput_opcode;
struct wl_listener display_destroy; struct wl_listener display_destroy;