Hi all,
I found this bug while trying the GLX module for my TNT2 when it froze
my X server.
After some investigation, I found out that the problem lies in Mesa
(CVS as of 09/30, compiled with debug informations and with only the X
driver).
(gdb) r
Starting program: /usr/local/src/Mesa/Tests/testGL2
GenuineIntel cpu detected.
Program received signal SIGSEGV, Segmentation fault.
gl_compute_orflag (IM=0x81cdae0) at vbxform.c:457
457 andflag &= IM->Flag[i];
(gdb) bt
#0 gl_compute_orflag (IM=0x81cdae0) at vbxform.c:457
#1 0x8123024 in gl_maybe_transform_vb (IM=0x81cdae0) at vbxform.c:65
#2 0x8123082 in gl_flush_vb (ctx=0x81b28f8, where=0x819c9d0 "glMatrixMode") at
vbxform.c:89
#3 0x80b3db5 in gl_MatrixMode (ctx=0x81b28f8, mode=GL_MODELVIEW) at matrix.c:989
#4 0x804d466 in glMatrixMode (mode=GL_MODELVIEW) at api1.c:1957
#5 0x8049d22 in main ()
(gdb) p count
$1 = 135983552
The program is attached to this mail. It's not very important for me
that this bug is found as this program is really just an old glX
program, but you may find this interesting :-)
As I find the vertex buffer / transform code rather opaque, I did not
try to debug it further than looking a bit at the code for 'stupid'
errors.
To trigger the error, you only need to click on the window 15 times
(at least it 'works' that way on my config). This happens even when I
disable mouse-click events on the created window. My X version is
3.3.3.1 (the binary release of the nVidia X server).
I have a report that this crashes also on another's guy computer.
--
Lionel Ulmer - [EMAIL PROTECTED] - http://www.multimania.com/bbrox/
/* compile: cc -o glxsimple glxsimple.c -lGL -lX11 */
#include <stdio.h>
#include <stdlib.h>
#include <GL/glx.h> /* this includes the necessary X headers */
#include <GL/gl.h>
static int snglBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,None};
static int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None};
Display *dpy;
Window win;
GLfloat xAngle=42.0,yAngle=82.0,zAngle=112.0;
GLboolean doubleBuffer=GL_TRUE;
void fatalError(char *message) {
fprintf(stderr,"glxsimple: %s\n",message);
exit(1);
}
void redraw(void) {
static GLboolean displayListInited=GL_FALSE;
if (displayListInited) {
/* if display list already exists,just execute it */
glCallList(1);
} else {
/* otherwise compile and execute to create the display list */
glNewList(1,GL_COMPILE_AND_EXECUTE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* front face */
glBegin(GL_QUADS);
glColor3f(0.0,0.7,0.1); /* green */
glVertex3f(-1.0,1.0,1.0);
glVertex3f(1.0,1.0,1.0);
glVertex3f(1.0,-1.0,1.0);
glVertex3f(-1.0,-1.0,1.0);
/* back face */
glColor3f(0.9,1.0,0.0); /* yellow */
glVertex3f(-1.0,1.0,-1.0);
glVertex3f(1.0,1.0,-1.0);
glVertex3f(1.0,-1.0,-1.0);
glVertex3f(-1.0,-1.0,-1.0);
/* top side face */
glColor3f(0.2,0.2,1.0); /* blue */
glVertex3f(-1.0,1.0,1.0);
glVertex3f(1.0,1.0,1.0);
glVertex3f(1.0,1.0,-1.0);
glVertex3f(-1.0,1.0,-1.0);
/* bottom side face */
glColor3f(0.7,0.0,0.1); /* red */
glVertex3f(-1.0,-1.0,1.0);
glVertex3f(1.0,-1.0,1.0);
glVertex3f(1.0,-1.0,-1.0);
glVertex3f(-1.0,-1.0,-1.0);
glEnd();
glEndList();
displayListInited=GL_TRUE;
}
/* buffer swap does implicit glFlush */
if(doubleBuffer) glXSwapBuffers(dpy,win);
/* explicit flush for single buffered case */
else glFlush();
}
void main(int argc,char **argv) {
XVisualInfo *vi;
Colormap cmap;
XSetWindowAttributes swa;
GLXContext cx;
XEvent event;
GLboolean needRedraw=GL_FALSE,recalcModelView=GL_TRUE;
int dummy;
/*** (1) open a connection to the X server ***/
dpy=XOpenDisplay(NULL);
if (dpy==NULL) fatalError("could not open display");
/*** (2) make sure OpenGL's GLX extension supported ***/
if (!glXQueryExtension(dpy,&dummy,&dummy))
fatalError("X server has no OpenGL GLX extension");
/*** (3) find an appropriate visual ***/
/* find an OpenGL-capable RGB visual with depth buffer */
vi=glXChooseVisual(dpy,DefaultScreen(dpy),dblBuf);
if (vi==NULL) {
vi=glXChooseVisual(dpy,DefaultScreen(dpy),snglBuf);
if (vi==NULL) fatalError("no RGB visual with depth buffer");
doubleBuffer=GL_FALSE;
}
if(vi->class!=TrueColor)
fatalError("TrueColor visual required for this program");
/*** (4) create an OpenGL rendering context ***/
/* create an OpenGL rendering context */
cx=glXCreateContext(dpy,vi,/* no sharing of display lists */ None,
/* direct rendering if possible */ GL_FALSE);
if (cx==NULL) fatalError("could not create rendering context");
/*** (5) create an X window with the selected visual ***/
/* create an X colormap since probably not using default visual */
cmap=XCreateColormap(dpy,RootWindow(dpy,vi->screen),vi->visual,AllocNone);
swa.colormap=cmap;
swa.border_pixel=0;
swa.event_mask=ExposureMask | ButtonPressMask | StructureNotifyMask;
win=XCreateWindow(dpy,RootWindow(dpy,vi->screen),0,0,300,300,0,vi->depth,
InputOutput,vi->visual,
CWBorderPixel | CWColormap | CWEventMask,&swa);
XSetStandardProperties(dpy,win,"glxsimple","glxsimple",None,argv,argc,NULL);
/*** (6) bind the rendering context to the window ***/
glXMakeCurrent(dpy,win,cx);
/*** (7) request the X window to be displayed on the screen ***/
XMapWindow(dpy,win);
/*** (8) configure the OpenGL context for rendering ***/
glEnable(GL_DEPTH_TEST); /* enable depth buffering */
glDepthFunc(GL_LESS); /* pedantic, GL_LESS is the default */
glClearDepth(1.0); /* pedantic, 1.0 is the default */
/* frame buffer clears should be to black */
glClearColor(0.0,0.0,0.0,0.0);
/* set up projection transform */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,1.0,10.0);
/* establish initial viewport */
glViewport(0,0,300,300); /* pedantic, full window size is default viewport */
/*** (9) dispatch X events ***/
while (1) {
xAngle+=10.0;
yAngle+=1.0;
zAngle-=2.0;
glMatrixMode(GL_MODELVIEW);
/* reset modelview matrix to the identity matrix */
glLoadIdentity();
/* move the camera back three units */
glTranslatef(0.0,0.0,-3.0);
/* rotate by X, Y, and Z angles */
glRotatef(xAngle,0.1,0.0,0.0);
glRotatef(yAngle,0.0,0.1,0.0);
glRotatef(zAngle,0.0,0.0,1.0);
redraw();
}
}