自从我上次在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).