Reading file, corrupted data

c++, glfw, glsl, linux, opengl

Solution

FIRST OFF Switch to C++ instead of C-with-a-cpp extension to avoid shipwrecks like this.

Analysis:

Running under valgrind shows

==15579== Invalid read of size 1
==15579==    at 0x5B95C65: vfprintf (vfprintf.c:1623)
==15579==    by 0x5B9E768: printf (printf.c:35)
==15579==    by 0x4019C1: shader_load(unsigned int, char const*) (shaders.cpp:88)
==15579==    by 0x401B30: program_create(char const*, char const*) (shaders.cpp:120)
==15579==    by 0x401D65: main (in /tmp/ogl-jg-3/test)
==15579==  Address 0xb3018a6 is 0 bytes after a block of size 150 alloc'd
==15579==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
==15579==    by 0x401961: shader_load(unsigned int, char const*) (shaders.cpp:81)
==15579==    by 0x401B30: program_create(char const*, char const*) (shaders.cpp:120)
==15579==    by 0x401D65: main (in /tmp/ogl-jg-3/test)

It tells you exactly that it tries to read beyond the end of the buffer `tmp` which is allocated in line 81. It seems you are somehow assuming it is null-terminated. Which it isn't. Add that:

//wczytywanie
char *tmp = new char[iFileSize+1];
memset(tmp, 0, (iFileSize+1)*sizeof(char));
uint32 iBytes = (uint32) fread(tmp, sizeof(char), iFileSize, file); 
fclose(file);   
if (iBytes != iFileSize) printf("Warning: reading error possible!\n");

#ifdef _DEBUG_
    printf("----- SRC ----- (%d B)\n%s\n----- END -----\n", iBytes, tmp);
#endif

And I get semi-decent output. The GL window stays blank, though

Update

To make it clearer what I meant by switch to C++ here's the idea:

GLuint shader_load(GLenum type, const char filename[]) {
    if ((type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) || !filename) return 0;

    GLuint shader = glCreateShader(type);
    std::string src;
    {
        /* wczytywanie pliku shadera */
        std::ifstream ifs(filename, std::ios::binary);
        if (!std::getline(ifs, src, '\0'))
            std::cerr << "Warning: reading error possible!\n";
    }

#ifdef _DEBUG_
    std::cout << "----- SRC ----- " << src.size() << " B \n" << src << "\n----- END -----\n";
#endif

    /* przygotowanie shadera */
    const GLchar* sources[] = { src.c_str() };
    glShaderSource(shader, 1, sources, NULL);
    glCompileShader(shader); //kompilacja shadera

Problem

It seems I can't have my GLSL shaders compiled. Once in a while (mainly after editing a file), I get following error while compiling: ``` ----- SRC ----- (150 B) #version 330 core uniform mat4 mvpMatrix; in vec4 vertexPosition_modelspace; void main() { gl_Position = mvpMatrix * vertexPosition_modelspace; } gp! ----- END ----- SimpleTransform.vertexshader:Vertex shader failed to compile with the following errors: ERROR: 0:10: error(#132) Syntax error: 'gp' parse error ERROR: error(#273) 1 compilation errors. No code generated ``` It's quite strange since I swear the file doesn't contain that awkward `gp!` part. Nevertheless I investigated it with cat ``` #version 330 core uniform mat4 mvpMatrix; in vec4 vertexPosition_modelspace; void main() { gl_Position = mvpMatrix * vertexPosition_modelspace; } ``` and less ``` #version 330 core uniform mat4 mvpMatrix; in vec4 vertexPosition_modelspace; void main() { gl_Position = mvpMatrix * vertexPosition_modelspace; } ``` and both of them proved me right. I wonder what's causing this strange behaviour. Here's link to my project. You should be able to easily compile it by entering src directory and typing `make` (Linux only). It requires GLFW, GLEW, GLM and GL3. And the code itself: Loading shader files ``` GLuint shader_load(GLenum type, const char filename[]) { if ((type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) || !filename) return 0; /* wczytywanie pliku shadera */ FILE *file = fopen(filename, "rb"); //okreslenie rozmiaru pliku fseek(file, 0, SEEK_END); uint32 iFileSize = ftell(file); fseek(file, 0, SEEK_SET); //wczytywanie char *tmp = new char[iFileSize]; memset(tmp, 0, sizeof(tmp)); uint32 iBytes = (uint32) fread(tmp, sizeof(char), iFileSize, file); fclose(file); if (iBytes != iFileSize) printf("Warning: reading error possible!\n"); #ifdef _DEBUG_ printf("----- SRC ----- (%d B)\n%s\n----- END -----\n", iBytes, tmp); #endif /* przygotowanie shadera */ GLuint shader = glCreateShader(type); glShaderSource(shader, 1, const_cast<const GLchar**>(&tmp), NULL); delete[] tmp; glCompileShader(shader); //kompilacja shadera /* sprawdzenie statusu kompilacji */ int status = GL_FALSE; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); int logsize = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logsize); char *log = new char[logsize]; glGetShaderInfoLog(shader, logsize, NULL, log); printf("%s:%s", filename, log); delete[] log; if (status != GL_TRUE) return 0; return shader; } ```

Original source

Related problems