“stack corruption detected” when using glGetProgramiv

狂风中的少年 提交于 2019-12-24 06:43:04

问题


I am writing native Android OpenGLES 2 code.

When loading shaders (shader loading code is very similar to the NDK sample "hello-gl2"), my program does not link (shaders themselves compile without errors).

This code:

GLint linkStatus = GL_FALSE;
GLCALL(glGetProgramiv(programId, GL_LINK_STATUS, &linkStatus));
if (linkStatus != GL_TRUE) {

Returns false, so I proceed to calling

LOGE("Could not link program, gathering log...");
GLint bufLength = 0;
GLCALL(glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &bufLength));

Which never returns and crashes my app. LogCat shows in red:

04-19 15:24:55.369: A/<unknown>(29293): stack corruption detected: aborted
04-19 15:24:55.379: I/ActivityManager(101): Process x.x.x (pid 29293) has died.

I can assume that something goes wrong inside the log retrieving function, because I pass it a normal GLint reference, and this is the same code from the Google example...

I've tried skipping the length querying and just query the log directly, but it generates the same error.

I could post here the whole GLSL shader code but it would be more valuable to just have the log function working so I can debug it myself...

The full shader loading code:

GLuint OpenGLESHelper::loadShader(GLenum shaderType, const char* pSource) {
    GLuint shader;
    GLCALL(shader = glCreateShader(shaderType));
    if (shader) {
        GLCALL(glShaderSource(shader, 1, &pSource, NULL));
        GLCALL(glCompileShader(shader));
        GLint compiled = 0;
        GLCALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
        if (!compiled) {
            LOGE("Could not compile shader, retrieving log...");
            GLint infoLen = 0;
            GLCALL(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen));

            // Workaround
            if (infoLen == 0)
                infoLen = 4096;

            if (infoLen) {
                char* buf = (char*) malloc(infoLen);
                if (buf) {
                    GLCALL(glGetShaderInfoLog(shader, infoLen, NULL, buf));
                    LOGE("Could not compile shader %d:\n%s\n", shaderType, buf);
                    free(buf);
                }
                GLCALL(glDeleteShader(shader));
                shader = 0;
            }
        }
    }
    return shader;
}

ShaderProgram* OpenGLESHelper::createProgram(const char* pVertexSource,
        const char* pFragmentSource) {
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
    if (!vertexShader) {
        return 0;
    }

    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
    if (!pixelShader) {
        return 0;
    }

    GLuint programId;
    GLCALL(programId = glCreateProgram());
    if (programId) {
        GLCALL(glAttachShader(programId, vertexShader));
        GLCALL(glAttachShader(programId, pixelShader));
        GLCALL(glLinkProgram(programId));
        GLint linkStatus = GL_FALSE;
        GLCALL(glGetProgramiv(programId, GL_LINK_STATUS, &linkStatus));
        if (linkStatus != GL_TRUE) {
            LOGE("Could not link program, gathering log...");
            GLint bufLength = 0;
            GLCALL(glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &bufLength));

            if (bufLength) {
                char* buf = (char*) malloc(bufLength);
                if (buf) {
                    GLCALL(glGetProgramInfoLog(programId, bufLength, NULL, buf));
                    LOGE("Could not link program:\n%s\n", buf);
                    free(buf);
                }
            }
            GLCALL(glDeleteProgram(programId));
            programId = 0;
        }
    }

    ShaderProgram* program = new ShaderProgram;
    program->mProgramHandle = programId;

    GLCALL(
            program->mPositionAttributeHandle = glGetAttribLocation(programId, "vPosition"));
    GLCALL(
            program->mTexCoordAttributeHandle = glGetAttribLocation(programId, "a_TexCoordinate"));
    GLCALL(
            program->mTextureUniformHandle = glGetUniformLocation(programId, "rubyTexture"));
    GLCALL(
            program->mTextureSizeUniformHandle = glGetUniformLocation(programId, "rubyTextureSize"));

    return program;
}

The used preprocessor macros:

  #ifdef ANDROID_DEBUG_GL_CALLS
#define GLCALLLOG(x, before) \
    do { \
        if (before) \
            LOGD("calling '%s' (%s:%d)", x, __FILE__, __LINE__); \
        else \
            LOGD("returned from '%s' (%s:%d)", x, __FILE__, __LINE__); \
    } while (false)
#else
#define GLCALLLOG(x, before) do {  } while (false)
#endif

#define GLCALL(x) \
    do { \
        GLCALLLOG(#x, true); \
        (x); \
        GLCALLLOG(#x, false); \
        checkGlError(#x, __FILE__, __LINE__); \
    } while (false)

#define GLTHREADCHECK \
    do { \
        assert(pthread_self() == _main_thread); \
    } while (false)

#else
#define GLCALL(x) do { (x); } while (false)
#define GLTHREADCHECK do {  } while (false)
#endif

UPDATE

There was one particular shader pair which generated this weird behavior.

I found 2 other shader pairs that compile correctly, but when linked, generate a log with just "Link failed." - no info beside that.

Then I tried those 2 shader pairs (exact same APK) on a Jelly Bean AVD with GPU emulation, and they link together perfectly and my game works there.

Very, very, very inconsistent stuff here... Is the problem with my HTC Desire? What would be a good reference device for checking if my shaders are good or not?

来源:https://stackoverflow.com/questions/16104896/stack-corruption-detected-when-using-glgetprogramiv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!