From f8428d1063c6420ee43424269149a65f8c33812f Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Sat, 3 Mar 2018 11:37:02 +0100 Subject: [PATCH] xcb errors: optional dependency with improved messages Now message can look like: [xwayland/xwm.c:991] xcb error: op ChangeProperty (no minor), code Window (no extension), value 6291465 instead of this one when the lib is not available: [xwayland/xwm.c:999] xcb error: op 18:0, code 3, sequence 103, value 6291465 The value in case of Window is the window id, so we can tell what function applied on which window which is a good start. The sequence ought to be able to tell us more precisely which invocation it was, but we never log it when calling functions so is useless in practice and no longer logged. --- meson.build | 15 ++++++++++---- meson_options.txt | 1 + xwayland/meson.build | 1 + xwayland/xwm.c | 47 +++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index d5ae7863..1188f318 100644 --- a/meson.build +++ b/meson.build @@ -64,6 +64,7 @@ xcb_xfixes = dependency('xcb-xfixes') xcb_image = dependency('xcb-image') xcb_render = dependency('xcb-render') xcb_icccm = dependency('xcb-icccm', required: false) +xcb_errors = dependency('xcb-errors', required: get_option('enable_xcb_errors') == 'true') x11_xcb = dependency('x11-xcb') libcap = dependency('libcap', required: get_option('enable_libcap') == 'true') systemd = dependency('libsystemd', required: get_option('enable_systemd') == 'true') @@ -78,6 +79,10 @@ if xcb_icccm.found() conf_data.set('WLR_HAS_XCB_ICCCM', true) endif +if xcb_errors.found() and get_option('enable_xcb_errors') != 'false' + conf_data.set('WLR_HAS_XCB_ERRORS', true) +endif + if libcap.found() and get_option('enable_libcap') != 'false' conf_data.set('WLR_HAS_LIBCAP', true) wlr_deps += libcap @@ -164,10 +169,12 @@ summary = [ '----------------', 'wlroots @0@'.format(meson.project_version()), '', - ' libcap: @0@'.format(conf_data.get('WLR_HAS_LIBCAP', false)), - ' systemd: @0@'.format(conf_data.get('WLR_HAS_SYSTEMD', false)), - ' elogind: @0@'.format(conf_data.get('WLR_HAS_ELOGIND', false)), - ' xwayland: @0@'.format(conf_data.get('WLR_HAS_XWAYLAND', false)), + ' libcap: @0@'.format(conf_data.get('WLR_HAS_LIBCAP', false)), + ' systemd: @0@'.format(conf_data.get('WLR_HAS_SYSTEMD', false)), + ' elogind: @0@'.format(conf_data.get('WLR_HAS_ELOGIND', false)), + ' xwayland: @0@'.format(conf_data.get('WLR_HAS_XWAYLAND', false)), + ' xcb-icccm: @0@'.format(conf_data.get('WLR_HAS_XCB_ICCCM', false)), + ' xcb-errors: @0@'.format(conf_data.get('WLR_HAS_XCB_ERRORS', false)), '----------------', '' ] diff --git a/meson_options.txt b/meson_options.txt index 6434b43d..4812b6f8 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,5 @@ option('enable_libcap', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Enable support for capabilities') option('enable_systemd', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Enable support for logind') option('enable_elogind', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Enable support for logind') +option('enable_xcb_errors', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Use xcb-errors util library') option('enable_xwayland', type: 'boolean', value: true, description: 'Enable support X11 applications') diff --git a/xwayland/meson.build b/xwayland/meson.build index 2ccdf4cb..9d7f3f4a 100644 --- a/xwayland/meson.build +++ b/xwayland/meson.build @@ -15,6 +15,7 @@ lib_wlr_xwayland = static_library( xcb_image, xcb_render, xcb_icccm, + xcb_errors, xkbcommon, pixman, ], diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 549a3333..09f30d3d 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -19,6 +19,9 @@ #ifdef WLR_HAS_XCB_ICCCM #include #endif +#ifdef WLR_HAS_XCB_ERRORS + #include +#endif const char *atom_map[ATOM_LAST] = { "WL_SURFACE_ID", @@ -955,9 +958,47 @@ static void xwm_handle_focus_in(struct wlr_xwm *xwm, } static void xwm_handle_xcb_error(struct wlr_xwm *xwm, xcb_value_error_t *ev) { - wlr_log(L_ERROR, "xcb error: code %d, sequence %d, value %d, opcode %d:%d", - ev->error_code, ev->sequence, ev->bad_value, - ev->minor_opcode, ev->major_opcode); +#ifdef WLR_HAS_XCB_ERRORS + xcb_errors_context_t *err_ctx; + if (xcb_errors_context_new(xwm->xcb_conn, &err_ctx)) { + wlr_log(L_DEBUG, "xcb error happened, but could not allocate error context"); + goto log_raw; + } + + const char *major_name; + major_name = xcb_errors_get_name_for_major_code(err_ctx, ev->major_opcode); + if (!major_name) { + wlr_log(L_DEBUG, "xcb error happened, but could not get major name"); + xcb_errors_context_free(err_ctx); + goto log_raw; + } + + const char *minor_name; + minor_name = xcb_errors_get_name_for_minor_code(err_ctx, + ev->major_opcode, ev->minor_opcode); + + const char *error_name, *extension; + error_name = xcb_errors_get_name_for_error(err_ctx, ev->error_code, &extension); + if (!error_name) { + wlr_log(L_DEBUG, "xcb error happened, but could not get error name"); + xcb_errors_context_free(err_ctx); + goto log_raw; + } + + wlr_log(L_ERROR, "xcb error: op %s (%s), code %s (%s), value %"PRIu32, + major_name, minor_name ? minor_name : "no minor", + error_name, extension ? extension : "no extension", + ev->bad_value); + + xcb_errors_context_free(err_ctx); + return; +log_raw: +#endif + wlr_log(L_ERROR, + "xcb error: op %"PRIu8":%"PRIu16", code %"PRIu8", sequence %"PRIu16", value %"PRIu32, + ev->major_opcode, ev->minor_opcode, ev->error_code, + ev->sequence, ev->bad_value); + } /* This is in xcb/xcb_event.h, but pulling xcb-util just for a constant