title: Why does glGetProgramiv GL_ACTIVE_UNIFORMS occasionally return garbage and crash my program?
body: <p>I have adapted some code from Anton's opengl tutorial companion code found here: 
  <a href="https://github.com/capnramses/antons_opengl_tutorials_book/blob/master/02_shaders/main.c" rel="nofollow noreferrer">https://github.com/capnramses/antons_opengl_tutorials_book/blob/master/02_shaders/main.c</a> </p>
  
  <p>In testing the print_all or dump_all function to print everything about a shader, I have noticed in my log that <code>glGetProgramiv(shader_program, GL_ACTIVE_UNIFORMS, &amp;params)</code> will put a garbage value that is either extremely negative(and doesn't do anything due to the for loop check) or extremely positive and crashes my program at <code>glGetActiveUniform(shader_program, i, MAX_LENGTH, &amp;actual_length, &amp;size, &amp;type, name)</code> because it is only supposed to handle values of <code>i</code> up to <code>NUM_ACTIVE_UNIFORMS - 1</code>; and I am sure it isn't expecting a number over 1 million. I have also checked for the result of glGetError after the call and no error flags have been set.</p>
  
  <p>Here is my dump function and a picture of my log:</p>
  
  <pre><code>void dump_all(FILE* file, GLuint shader_program)
  {
      int params = -1;
  
      fprintf(file, "--------------------\nshader program %i info:\n", shader_program);
      glGetProgramiv (shader_program, GL_LINK_STATUS, &amp;params);
      fprintf(file, "GL_LINK_STATUS = %i\n", params);
  
      glGetProgramiv (shader_program, GL_ATTACHED_SHADERS, &amp;params);
      fprintf(file,"GL_ATTACHED_SHADERS = %i\n", params);
  
      glGetProgramiv (shader_program, GL_ACTIVE_ATTRIBUTES, &amp;params);
      fprintf(file, "GL_ACTIVE_ATTRIBUTES = %i\n", params);
  
      const int MAX_LENGTH = 64;
      int i;
      for (i = 0; i &lt; params; i++)
      {
          char name[MAX_LENGTH];
          int actual_length = 0; // not used atm.
          int size = 0;
          GLenum type;
          glGetActiveAttrib (shader_program, i, MAX_LENGTH, &amp;actual_length, &amp;size, &amp;type, name);
          if (size &gt; 1)
          {
              int j;
              for (j = 0; j &lt; size; j++)
              {
                  char long_name[MAX_LENGTH];
                  int location;
  
                  sprintf (long_name, "%s[%i]", name, j);
                  location = glGetAttribLocation (shader_program, long_name);
                  fprintf (file, "  %i) type:%s name:%s location:%i\n",
                      i, gl_type_to_string(type), long_name, location);
              }
          }
          else
          {
              int location = glGetAttribLocation (shader_program, name);
              fprintf(file, "  %i) type:%s name:%s location:%i\n", i, gl_type_to_string (type), name, location);
          }
      }
  
      printf("\nbefore the active uniform call\n");
      glGetProgramiv (shader_program, GL_ACTIVE_UNIFORMS, &amp;params);
      GLenum error = glGetError();
      printf("\nThere is an error (0 for no error and 1 for an error): %d\n", error != GL_NO_ERROR);
      printf("\nglGetError: %d\n", error);
      printf("\nafter the get active uniform call\n");
      fprintf(file, "GL_ACTIVE_UNIFORMS = %i\n", params);
      for (i = 0; i &lt; params; i++)
      {
          char name[MAX_LENGTH];
          int actual_length = 0; // not used atm.
          int size = 0;
          GLenum type;
          printf("\nright before the thing\n");
          glGetActiveUniform (shader_program, i, MAX_LENGTH, &amp;actual_length, &amp;size, &amp;type, name);
          printf("\nright after the thign\n");
          if (size &gt; 1)
          {
              printf("\nin the if block\n");
              int j;
              for (j = 0; j &lt; size; j++)
              {
                  char long_name[MAX_LENGTH];
                  int location;
  
                  sprintf (long_name, "%s[%i]", name, j);
                  location = glGetUniformLocation (shader_program, long_name);
                  fprintf(file, "  %i) type:%s name:%s location:%i\n",
                      i, gl_type_to_string (type), long_name, location);
              }
          }
          else
          {
              printf("\nin the else block\n");
              int location = glGetUniformLocation (shader_program, name);
              fprintf(file, "  %i) type:%s name:%s location:%i\n",
                      i, gl_type_to_string (type), name, location);
          }
      }
  
      print_program_info_log(file, shader_program);
  }
  </code></pre>
  
  <p>My log when the value is negative:  <a href="https://i.stack.imgur.com/Xu9nq.png" rel="nofollow noreferrer">http://i.stack.imgur.com/Xu9nq.png</a></p>
  
  <p>My log when the value is huge and crashes the program : <a href="https://i.stack.imgur.com/QBP1o.png" rel="nofollow noreferrer">http://i.stack.imgur.com/QBP1o.png</a></p>
  
  <p>Note: I am running the application from a directory where the files cannot be found. Also, I have yet to make a call to glUseProgram() anywhere. So, I am dumping the contents of a shader that hasn't been successfully linked or even has any successfully compiled shaders attached to it.</p>
  
  <p>This is an intermittent problem; most of the time, the log will correctly print out 0 for active uniforms. So far, I have seen three outcomes; 1.) The number is too big and it crashes. 2.) The number is crazily negative and doesn't crash . 3.) The number is big but not too big and spends a lot of time in the loops below the crashing call, just printing out garbage.  </p>
  
  <p>Is this a Driver bug, or am I doing something that is inherently undefined? </p>
  
  <p><strong>EDIT 1:</strong> </p>
  
  <p>In the case that the call to <code>glGetProgramiv(shader_program, GL_ACTIVE_UNIFORMS, &amp;params)</code> returns a huge number, the call to <code>glGetActiveUniform (shader_program, i, MAX_LENGTH, &amp;actual_length, &amp;size, &amp;type, name)</code> crashes in the first iteration of the for loop below it with the value of zero for <code>i</code>. However, when <code>glGetProgramiv</code> returns 0 for the active uniforms like it should, a call to <code>glGetActiveUniform</code> with 0 for <code>i</code> doesn't crash(I hard coded the for loop to go around once). This makes me feel like there is more going on here than just uninitialized data being returned to me.</p>
  
  <p><strong>EDIT 2</strong>
  As requested, here is a minimal example program that gives weird values:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  #undef main
  int main(int argc, char ** argv)
  {
      SDL_Init(SDL_INIT_EVERYTHING);
  
      SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
      SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
      SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
      SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
      SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
      SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
      SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
  
      SDL_Window *window = SDL_CreateWindow("Example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
      if(!window)
      {
          printf("no window created : %s\n", SDL_GetError());
      }
      SDL_GLContext context = SDL_GL_CreateContext(window);
      SDL_GL_MakeCurrent(window, context);
      SDL_GL_SetSwapInterval(1);
  
      glewExperimental = GL_TRUE;
      GLenum err = glewInit();
      if(err != GLEW_OK)
      {
          printf("glew failed to init: %s", glewGetErrorString(err));
          return -1;
      }
  
      GLuint program = glCreateProgram();
  
      glLinkProgram(program); // I can create and attach shaders, compile them, or whatever; I get the same result.
  
      GLint num;
      glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &amp;num);
  
      printf("NUM UNIFORMS: %d", num);
  
      int run_loop = 1;
      while(run_loop)
      {
          SDL_Event event;
          while(SDL_PollEvent(&amp;event))
          {
              switch(event.type)
              {
                  case SDL_QUIT:
                      SDL_Quit();
                      run_loop = 0;
                      break;
                  default:
                      break;
              }
          }
          SDL_GL_SwapWindow(window);
      }   
      return 0;
  }
  </code></pre>