Paste: nvidia gtk bug
Author: | erg (blei) |
Mode: | factor |
Date: | Tue, 7 Feb 2012 22:08:21 |
Plain Text |
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <gtk/gtk.h>
/*
#include <gtk/gtkgl.h>
*/
/*
* NOTE: at first I tried to create a GL context to reproduce the hang (see the
* out-commented code.) But apparently it's not required to actually use GL at
* all, linking to GL makes the bug appear.
*
* Build this with:
* gcc foo.c -Wall `pkg-config --libs --cflags gtk+-2.0` -lGL
* (If you are on Ubuntu, you might have to add -Wl,--no-as-needed to
* reproduce)
*
* The commented code requires (but is not needed to reproduce):
* gcc foo.c -Wall `pkg-config --libs --cflags gtk+-2.0 gtkglext-1.0`
*
* Description:
* An empty window opens. When you close the window, the executable doesn't
* stop, but appears to hit an endless loop. If you connect to the executable
* with GDB, you can see that the endless loop happens in the NVidia driver.
* My guess as to the cause of the loop is that the NVidia driver intercepts
* the read() call and waits for it to finish (in a spinning loop) in an
* function that was registered using at_exit() or something similar.
*
* System information:
* Arch Linux, Kernel 3.2.2
* Nvidia 290.10
* GTK 2.24.9
*
* Thank you for looking into this :)
*/
void *read_stuff(void *data) {
sigset_t mask;
sigfillset(&mask);
sigdelset(&mask, SIGUSR2);
sigdelset(&mask, SIGTTIN);
sigdelset(&mask, SIGTERM);
sigdelset(&mask, SIGQUIT);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
int unused;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &unused);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &unused);
while (1) {
char buf[1000];
// read from stdin
read(0, buf, 1000);
}
return NULL;
}
void start_read_thread() {
pthread_t thread_id;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&thread_id, &attr, read_stuff, NULL);
}
int main(int argc, char **argv) {
start_read_thread();
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/*
int config_attribs[] = {GDK_GL_USE_GL, GDK_GL_RGBA, GDK_GL_DOUBLEBUFFER, GDK_GL_ATTRIB_LIST_NONE};
GdkGLConfig *config = gdk_gl_config_new(config_attribs);
gtk_widget_set_gl_capability(window, config, NULL, TRUE, GDK_GL_RGBA_TYPE);
*/
g_signal_connect(window, "delete-event", gtk_main_quit, NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
New Annotation