X错误的失败请求:X_ShmPutImage上的BadMatch |主要操作码130 |次操作码3

时间:2019-12-13 13:09:59

标签: c opengl x11 mesa glx

自从我上次在Gentoo上进行系统升级以来,我无法运行我的一些代码:window_management.c,该代码在升级前没有任何警告或错误。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>

#include "common.h"
#include "extensions.h"
#include "text_pointer.h"
#include "window_management.h"

static void (*cursor_position_callback)(int xpos, int ypos) = 0;
void (*mouse_button_callback)(int xpos, int ypos, int button, int action) = 0;

#ifdef DSTUDIO_RELY_ON_X11

#define DSTUDIO_X11_INPUT_MASKS \
    ExposureMask | \
    KeyPressMask | \
    KeyReleaseMask | \
    ButtonPressMask | \
    ButtonReleaseMask | \
    VisibilityChangeMask

#define GLX_CONTEXT_MAJOR_VERSION_ARB       0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB       0x2092

typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);

static int ctx_error_occurred = 0;
static int window_alive = 1;
static int refresh_all = 1;
static Display              *display = NULL;
static Window               window;
static XVisualInfo          * visual_info;
static Colormap             color_map;
static XEvent               x_event;
static XEvent               x_sent_expose_event;
static GLXContext           opengl_context;
static int visual_attribs[] = {
      GLX_X_RENDERABLE    , True,
      GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
      GLX_RENDER_TYPE     , GLX_RGBA_BIT,
      GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
      GLX_RED_SIZE        , 8,
      GLX_GREEN_SIZE      , 8,
      GLX_BLUE_SIZE       , 8,
      GLX_ALPHA_SIZE      , 8,
      GLX_DEPTH_SIZE      , 24,
      GLX_STENCIL_SIZE    , 8,
      GLX_DOUBLEBUFFER    , True,
      None
};

static int glx_major, glx_minor;
static unsigned int keyboard_chars_map_mode = 0;

static int ctx_error_handler( Display *dpy, XErrorEvent *ev ) {
    (void) dpy;
    (void) ev;
    ctx_error_occurred = 1;
    return 0;
}

static void creating_color_map(XVisualInfo * vi, Window * root_window, XSetWindowAttributes * swa) {
    color_map = XCreateColormap(display, *root_window, vi->visual, AllocNone);
    swa->colormap = color_map;
    swa->background_pixmap = None ;
    swa->border_pixel      = 0;
    swa->event_mask        = ExposureMask | StructureNotifyMask |PointerMotionMask;
}

void destroy_context() {
    glXDestroyContext(display, opengl_context);
    XDestroyWindow(display, window);
    XCloseDisplay(display);
}

static void get_visual_info(GLXFBConfig * best_frame_buffer_config) {
    int fbcount;
    int best_frame_buffer_config_index = -1;
    int worst_fbc = -1;
    int best_num_samp = -1;
    int worst_num_samp = 999;

    GLXFBConfig * frame_buffer_config = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount);
    DSTUDIO_EXIT_IF_NULL(frame_buffer_config)

    for (int i=0; i<fbcount; ++i) {
        visual_info = glXGetVisualFromFBConfig( display, frame_buffer_config[i] );
        if (visual_info) {
            int samp_buf, samples;
            glXGetFBConfigAttrib( display, frame_buffer_config[i], GLX_SAMPLE_BUFFERS, &samp_buf );
            glXGetFBConfigAttrib( display, frame_buffer_config[i], GLX_SAMPLES       , &samples  );
            #ifdef DSTUDIO_DEBUG
                printf("Matching fbconfig %d, visual ID 0x%2lux: SAMPLE_BUFFERS = %d, SAMPLES = %d\n", i, visual_info->visualid, samp_buf, samples );
            #endif
            if ( best_frame_buffer_config_index < 0 || (samp_buf && samples > best_num_samp)) {
                best_frame_buffer_config_index = i; 
                best_num_samp = samples;
            }
            if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp ) {
                worst_fbc = i;
                worst_num_samp = samples;
            }
        }
        XFree(visual_info);
    }

    *best_frame_buffer_config = frame_buffer_config[ best_frame_buffer_config_index ];
    XFree( frame_buffer_config );

    // Get a visual
    visual_info = glXGetVisualFromFBConfig( display, *best_frame_buffer_config );
    #ifdef DSTUDIO_DEBUG
        printf( "Chosen visual ID = 0x%lux\n", visual_info->visualid );
    #endif
}

void init_context(const char * window_name, int width, int height) {
    DSTUDIO_EXIT_IF_NULL(XInitThreads());
    int (*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctx_error_handler);
    Window root_window;
    XSetWindowAttributes swa;
    XSizeHints * size_hints;

    display = XOpenDisplay(NULL);
    DSTUDIO_EXIT_IF_NULL(display)

    DSTUDIO_EXIT_IF_NULL(glXQueryVersion( display, &glx_major, &glx_minor ))
    DSTUDIO_EXIT_IF_FAILURE( glx_major == 1  &&  (glx_minor < 3))
    DSTUDIO_EXIT_IF_FAILURE( glx_major < 1 )

    GLXFBConfig best_frame_buffer_config;
    get_visual_info(&best_frame_buffer_config);
    DSTUDIO_EXIT_IF_NULL(visual_info)

    root_window = RootWindow(display, visual_info->screen);
    creating_color_map(visual_info, &root_window, &swa);

    window = XCreateWindow(display, root_window, 0, 0, width, height, 0, visual_info->depth, InputOutput, visual_info->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);

    DSTUDIO_EXIT_IF_NULL(window)

    size_hints = XAllocSizeHints();
    size_hints->flags = PMinSize | PMaxSize;
    size_hints->min_width = width;
    size_hints->min_height = height;
    size_hints->max_width = width;
    size_hints->max_height = height;

    XSetWMSizeHints(display, window, size_hints, XA_WM_NORMAL_HINTS);
    Atom delWindow = XInternAtom(display, "WM_DELETE_WINDOW", 0);
    XSetWMProtocols(display , window, &delWindow, 1);

    XSelectInput(display, window, DSTUDIO_X11_INPUT_MASKS | ButtonMotionMask);
    XkbSetDetectableAutoRepeat (display, 1, NULL);

    XFree(visual_info);
    XMapWindow(display, window);
    XStoreName(display, window, window_name);

    // Begin OpenGL context creation

    const char *glx_exts = glXQueryExtensionsString(display, DefaultScreen( display ));
    glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
    glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );

    if ( !is_extension_supported( glx_exts, "GLX_ARB_create_context" ) || !glXCreateContextAttribsARB ) {
        #ifdef DSTUDIO_DEBUG
            printf("glXCreateContextAttribsARB() not found. Using old-style GLX context.\n");
        #endif
        opengl_context = glXCreateNewContext( display, best_frame_buffer_config, GLX_RGBA_TYPE, 0, 1);
    }
    else {
        int context_attribs[] = {
            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
            GLX_CONTEXT_MINOR_VERSION_ARB, 3,
            GLX_CONTEXT_PROFILE_MASK_ARB,   GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
            //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
            None
        };

        opengl_context = glXCreateContextAttribsARB(display, best_frame_buffer_config, 0, 1, context_attribs);
    }

    // Sync to ensure any errors generated are processed.
    XSync(display, 0);
    DSTUDIO_EXIT_IF_FAILURE( ctx_error_occurred && opengl_context == 0)
    XSetErrorHandler(old_handler);

    #ifdef DSTUDIO_DEBUG
        if (!glXIsDirect(display, opengl_context)) {
            printf("Indirect GLX rendering context obtained\n");
        }
        else {
            printf("Direct GLX rendering context obtained\n");
        }
    #endif
    glXMakeCurrent( display, window, opengl_context );
}

void send_expose_event() {
    memset(&x_sent_expose_event, 0, sizeof(x_sent_expose_event));
    x_sent_expose_event.xexpose.serial = clock();
    x_sent_expose_event.type = Expose;
    x_sent_expose_event.xexpose.send_event = 1;
    x_sent_expose_event.xexpose.display = display;
    XSendEvent(display, window, 1, ExposureMask, &x_sent_expose_event);
    XFlush(display);
}

void swap_window_buffer() {
    glXSwapBuffers(display, window);
}

#endif

使用以下输出调用glXSwapBuffers()时,我的代码崩溃:

X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  130 (MIT-SHM)
  Minor opcode of failed request:  3 (X_ShmPutImage)
  Serial number of failed request:  52
  Current serial number in output stream:  53

我注意到glxgears在我的盒子上有类似的问题,但没有崩溃。该错误仅在退出glxgears并产生以下内容时出现:

X Error of failed request:  BadDrawable (invalid Pixmap or Window parameter)
  Major opcode of failed request:  130 (MIT-SHM)
  Minor opcode of failed request:  3 (X_ShmPutImage)
  Resource id in failed request:  0x2600002
  Serial number of failed request:  912
  Current serial number in output stream:  913

我首先尝试重新编译内核,xorg驱动程序,xorg服务器,mesa和xf86-video-intel(是的,我使用的是英特尔第三代产品),但是没有任何进展。

由于glxgears运行良好,即使上述软件包中的bug可能是错误的,也许这里我做错了。

编辑1 :如注释中所建议,我已经使用 -fsanitize = address 编译了我的代码,并获得了以下输出:

=================================================================
==8391==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 2048 byte(s) in 1 object(s) allocated from:
    #0 0x7fa74669d878 in __interceptor_malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/libasan.so.5+0x10c878)
    #1 0x55c7722b61e1 in load_shader /home/http/dev/github/DStudio/src/ui.c:357
    #2 0x55c7722b3fb9 in create_shader_program /home/http/dev/github/DStudio/src/ui.c:113
    #3 0x55c7722ab509 in ui_thread /home/http/dev/github/DStudio/src/dsandgrains/ui.c:305
    #4 0x7fa7462bf457 in start_thread (/lib64/libpthread.so.0+0x8457)

Direct leak of 600 byte(s) in 5 object(s) allocated from:
    #0 0x7fa74669d878 in __interceptor_malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/libasan.so.5+0x10c878)
    #1 0x7fa745c9371e in __getdelim (/lib64/libc.so.6+0x7571e)
    #2 0x55c7722af580 in get_proc_memory_usage /home/http/dev/github/DStudio/src/fileutils.c:119
    #3 0x55c7722b1a42 in update_system_usage /home/http/dev/github/DStudio/src/system_usage.c:71
    #4 0x7fa7462bf457 in start_thread (/lib64/libpthread.so.0+0x8457)

Direct leak of 600 byte(s) in 5 object(s) allocated from:
    #0 0x7fa74669d878 in __interceptor_malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/libasan.so.5+0x10c878)
    #1 0x7fa745c9371e in __getdelim (/lib64/libc.so.6+0x7571e)
    #2 0x55c7722af580 in get_proc_memory_usage /home/http/dev/github/DStudio/src/fileutils.c:119
    #3 0x55c7722b196f in update_system_usage /home/http/dev/github/DStudio/src/system_usage.c:56
    #4 0x7fa7462bf457 in start_thread (/lib64/libpthread.so.0+0x8457)

Direct leak of 120 byte(s) in 1 object(s) allocated from:
    #0 0x7fa74669d878 in __interceptor_malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/libasan.so.5+0x10c878)
    #1 0x7fa745c9371e in __getdelim (/lib64/libc.so.6+0x7571e)
    #2 0x55c7722afa87 in set_physical_memory /home/http/dev/github/DStudio/src/fileutils.c:169
    #3 0x55c7722a693b in main /home/http/dev/github/DStudio/src/dsandgrains/main.c:36
    #4 0x7fa745c41e6a in __libc_start_main (/lib64/libc.so.6+0x23e6a)

Direct leak of 80 byte(s) in 1 object(s) allocated from:
    #0 0x7fa74669da68 in __interceptor_calloc (/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/libasan.so.5+0x10ca68)
    #1 0x55c7722b7e7b in init_context /home/http/dev/github/DStudio/src/window_management.c:172
    #2 0x55c7722ab4b5 in ui_thread /home/http/dev/github/DStudio/src/dsandgrains/ui.c:295
    #3 0x7fa7462bf457 in start_thread (/lib64/libpthread.so.0+0x8457)

Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7fa74669d878 in __interceptor_malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/libasan.so.5+0x10c878)
    #1 0x55c7722b5242 in init_ui_elements /home/http/dev/github/DStudio/src/ui.c:246
    #2 0x55c7722a96a0 in init_ui /home/http/dev/github/DStudio/src/dsandgrains/ui.c:154
    #3 0x55c7722ab513 in ui_thread /home/http/dev/github/DStudio/src/dsandgrains/ui.c:307
    #4 0x7fa7462bf457 in start_thread (/lib64/libpthread.so.0+0x8457)

SUMMARY: AddressSanitizer: 3464 byte(s) leaked in 14 allocation(s).

0 个答案:

没有答案