Strange unhandled exception in Cg shader.
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?
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.
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.
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.
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
Popular Topics
Advertisement