Strange unhandled exception in Cg shader.

Started by
4 comments, last by cohr 15 years, 6 months ago
Im building this ray-tracer in Cg shading language. It all works fine when i run the program from inside Visual Studio. Funny thing is, it crashes when I start the program from the desktop with this error: "Unhandled exception at 0x7c911669 in CG-Raytracer.exe: 0xC0000005: Access violation reading location 0x00000000." in ntdll.dll Choosing debug reveals the following line: fragmentProgram = cgCreateProgramFromFile(context, CG_SOURCE, CWD "Ray-frag.cg", fragmentProfile, NULL, NULL); Where the error occours. Yes, the fragment program is very large 2809 GPU instructions, and contains a lot of warnings. If I reduce the shader program the problem goes away, but that is not an option. anyone got an idea to eleminate this bug/crash?
Advertisement
Shaders don't throw exceptions on the CPU, since they don't run on the CPU. Your exception is due to a NULL pointer dereference. You probably have a memory/pointer/stack or heap corruption related bug somewhere in your CPU side code that sends an invalid pointer to cgCreateProgramFromFile.
I'm well aware that shaders can't throw exceptions.
And yes your are right when you say it's an Null pointer exception.
The program code is very small, and I'm certain that I am not passing any NULL pointer to:

fragmentProgram = cgCreateProgramFromFile(context, CG_SOURCE, CWD "Ray-frag.cg",fragmentProfile, NULL, NULL);

Last two NULL are just compiler parameters. if parameter 6 is NULL "main" is assumed to be the entry point to the shader. Parameter 7 is extra arguments for the compiler.

I have discovered if i pre-compile the fragment program by using the command promt and cgc.exe. And load the shader using this line instead:

fragmentProgram = cgCreateProgramFromFile(context, CG_OBJECT, CWD "Ray-frag.fp",fragmentProfile, "main", NULL);

The program will not crash when running from the desktop.
why shouldn't you precompile your shaders?
My Blog - http://www.freakybytes.org
Quote:Original post by cohr
I'm well aware that shaders can't throw exceptions.
And yes your are right when you say it's an Null pointer exception.
The program code is very small, and I'm certain that I am not passing any NULL pointer to:


If the program is short, can you post the whole code ? The thing with memory corruption is that the indicated line/place in program is usually red herring - the memory was corrupted some time before you get the access violation. It can be simple one-off error or uninitialized variable etc.

That all said, you can still be looking at bug in the Cg library/drivers, but before you submit bug report to NVIDIA, you should thoroughly check your program.
Here is the source for my crashing app.
I have left out glut callback functions because the app crashes before control is passed to glut.

#include <windows.h>#include <GL/glew.h>#include <GL/glut.h>#include <Cg/cg.h>#include <Cg/cgGL.h>#include <IL/il.h>#include <IL/ilu.h>#include <Util/DisplayText.h>#include <Util/TrackBall.h>using namespace std;using namespace Util;using namespace CGLA;using namespace Graphics;DisplayText displaytext;TrackBall *ball;int old_state=GLUT_UP;CGcontext context;CGprogram vertexProgram, fragmentProgram;CGprofile vertexProfile, fragmentProfile;GLuint Texture0,Texture1;static void handleCgError();static void LoadCgPrograms();static void ChooseProfiles();static bool loadTexture(char *filename, GLuint *textureName, GLint texParam);int WINX = 320;int WINY = 240;float alpha = 0;float x = 0.0 ,y = 0.0;#ifndef CWD# define CWD ""#endifbool loadTexture(char *filename, GLuint *textureName, GLint texParam){	// Initialize image loading library (DevIL)	ilInit();	iluInit();		// Enable conversion from palette to RGB	ilEnable(IL_CONV_PAL);	// Create and bind an image.	ILuint  ImgId;	ilGenImages(1, &ImgId);	ilBindImage(ImgId);	// Load the image - abort program if it fails.	if(!ilLoadImage(filename))	{		MessageBox(NULL,"File not found","ERROR",MB_OK);		exit(0);	}else{		printf("File loaded!\n");	}	ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);	// Get dimensions of image.	int size_x = ilGetInteger(IL_IMAGE_WIDTH);	int size_y = ilGetInteger(IL_IMAGE_HEIGHT);	int bytes_per_pixel = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);	//Set a pointer to point to the first byte of the image.	const unsigned char* image = ilGetData();	//Create and bind a texture name	glGenTextures(1, textureName);	glBindTexture(GL_TEXTURE_2D, *textureName);	// Setup the texture interpolation	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //GL_LINEAR or GL_NEAREST	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //GL_LINEAR_MIPMAP_LINEAR	// Specify how we deal with wrapping.	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam); 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam);	// Build a pyramid of texture images.	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, 										size_x, size_y,											GL_RGB, GL_UNSIGNED_BYTE, 										image);	return true;}static void handleCgError() {	MessageBox(NULL,cgGetErrorString(cgGetError()),"ERROR",MB_OK);	exit(1);}static void ChooseProfiles(){	if (cgGLIsProfileSupported(CG_PROFILE_VP40))		vertexProfile = CG_PROFILE_VP40;	else {		MessageBox(NULL,"Profile VP40 is not avaliable on your system","ERROR",MB_OK);		exit(1);	}	if (cgGLIsProfileSupported(CG_PROFILE_FP40))		fragmentProfile = CG_PROFILE_FP40;	else {		MessageBox(NULL,"Profile FP40 is not avaliable on your system","ERROR",MB_OK);		exit(1);	}}static void LoadCgPrograms(){	assert(cgIsContext(context));		vertexProgram = cgCreateProgramFromFile(context, CG_SOURCE, CWD "Ray-vert.cg", vertexProfile, NULL, NULL);		if (!cgIsProgramCompiled(vertexProgram))		cgCompileProgram(vertexProgram);	cgGLEnableProfile(vertexProfile);	cgGLLoadProgram(vertexProgram);	//fragmentProgram = cgCreateProgramFromFile(context, CG_OBJECT, CWD "Ray-frag.fp",fragmentProfile, "main", NULL);	fragmentProgram = cgCreateProgramFromFile(context, CG_SOURCE, CWD "Ray-frag.cg",fragmentProfile, "main", NULL);	if (!cgIsProgramCompiled(fragmentProgram))		cgCompileProgram(fragmentProgram);	cgGLEnableProfile(fragmentProfile);	cgGLLoadProgram(fragmentProgram);	// Disable once loaded and compiled	cgGLDisableProfile(vertexProfile);	cgGLDisableProfile(fragmentProfile);}// ----------------------------------------// setup OpenGL projection matrix// ----------------------------------------void init_gl(int w, int h){	// We switch to projection matrix model	glMatrixMode(GL_PROJECTION);		// Clear projection matrix.	glLoadIdentity();	// Specify a perspective projection	gluPerspective(53,float(w)/h,0.1,200.0);	// Go back to modelview mode.	glMatrixMode(GL_MODELVIEW);}int main(int argc, char**argv){	// Initialize glut	glutInit(&argc,argv);	glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE);	glutInitWindowSize(WINX,WINY);	glutCreateWindow("Cg-Raytracer");	// Initialize call back functions. 	glutMouseFunc(mouse);	glutMotionFunc(motion);	glutDisplayFunc(display);	glutIdleFunc(animate);	glutKeyboardFunc(keyhandler);	glutIgnoreKeyRepeat(true);	glutReshapeFunc(reshape);	// Set colour for background clearing	glClearColor(0,0,0,0);	// Initialize OpenGL	init_gl(WINX,WINY);	glEnable(GL_DEPTH_TEST);	loadTexture("earth.tga",&Texture0,GL_REPEAT); //GL_CLAMP_TO_EDGE	loadTexture("green.tga",&Texture1,GL_REPEAT);	glEnable(GL_TEXTURE_2D);	// Initialize OpenGL extensions.	glewInit();		cgSetErrorCallback(handleCgError);	context = cgCreateContext();	//AvaliableProfiles();	ChooseProfiles();	LoadCgPrograms();		Vec3f v(0,0,0);	ball = new TrackBall(v, 40,40,WINX,WINY);	ball->set_eye_dist(10.0f);		displaytext.set_offset(-15,5);	displaytext.add_framerate();		glutMainLoop();	delete ball;	return 0;}

This topic is closed to new replies.

Advertisement