Crash in SDL_GL_ExtensionSupported()

I’m seeing a SIGSEGV crash in SDL_video.c from this (deduced) call backtrace:

SDL_GL_ExtensionSupported()
  isAtLeastGL3()
    SDL_atoi()
      atoi()
        strtoimax()

This is consistent with the string buffer being invalid, casting suspicion on this code:

glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
if (!glGetStringFunc) {
    return SDL_FALSE;
}

if (isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) {

The documentation of SDL_GL_GetProcAddress() specifically warns that “Some OpenGL drivers, on all platforms, will return NULL if a function isn’t supported, but you can’t count on this behavior” so that might be exactly what is happening here.

glGetString is a valid function in every OpenGL version, so I don’t think that’s what’s happening for you.

SDL_GL_ExtensionSupported should only be called while there’s an active OpenGL context on the thread which calls it, otherwise it could cause a crash.

So why is its address being obtained at run time?

The crash log definitely shows the buffer being passed to isAtLeastGL3() being invalid so I don’t know how that can arise otherwise.

I/DEBUG   (   97): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00001f02
I/DEBUG   (   97):     r0 00001f02  r1 400754d6  r2 00001f02  r3 00001f02
I/DEBUG   (   97): backtrace:
I/DEBUG   (   97):     #00  pc 0002423a  /system/lib/libc.so (strtoimax+25)
I/DEBUG   (   97): memory near r0:
I/DEBUG   (   97):     00001ee0 ffffffff ffffffff ffffffff ffffffff  
I/DEBUG   (   97):     00001ef0 ffffffff ffffffff ffffffff ffffffff  
I/DEBUG   (   97):     00001f00 ffffffff ffffffff ffffffff ffffffff  

I’m not calling it directly from my code. Looks like it gets called eventually from SDL_CreateRenderer()

So why is its address being obtained at run time?

OpenGL drivers provide OpenGL functions through dynamic libraries. Some platforms have a shim so a common baseline is always available no matter which driver is installed, but not every platform does this. SDL would need to link with a specific driver at build time (and thus exclude other drivers and driver versions at runtime) if it wanted to avoid loading the glGetString function pointer at runtime, on some platforms.

As long as an OpenGL context has been successfully created and set active on the current thread, and as long as SDL_GL_GetProcAddress is looking in the right place (e.g. there isn’t a mismatch between the graphics driver which the context is using, and where SDL_GL_GetProcAddress is searching in), SDL_GL_GetProcAddress(“glGetString”) should always produce a valid function pointer.

Do you have more details about the platform, graphics driver, etc. you’re using?

A quick look at the code in SDL_render_gles.c suggests that a context has been created prior to SDL_GL_ExtensionSupported() being called. However I have in the past indeed had problems with SDL_GL_GetProcAddress() “looking in the right place” as I reported here.

I’m debugging by ‘remote control’ since I have no access to the device in question, which is this. Although it runs Android it is clearly a far from conventional platform (not least because it apparently costs about $40,000!). I have asked for details of its graphics drivers because it seems likely that’s where the incompatibility originates.

If I comment out the crashing code in SDL_video.c (forcing isAtLeastGL3() to return SDL_FALSE) it then fails with this:

W/SurfaceFlinger(   98): no suitable EGLConfig found, trying without EGL_FRAMEBUFFER_TARGET_ANDROID
W/SurfaceFlinger(   98): no suitable EGLConfig found, trying without EGL_RECORDABLE_ANDROID
W/SurfaceFlinger(   98): no suitable EGLConfig found, trying with 16-bit color allowed
E/SurfaceFlinger(   98): no suitable EGLConfig found, giving up
E/SurfaceFlinger(   98): EGLContext creation failed
F/SurfaceFlinger(   98): couldn't create EGLContext

Since it got into SDL_atoi before crashing, it suggests that you got a (presumably valid) function pointer for glGetString, but it returned a non-NULL but invalid pointer for GL_VERSION.

Indeed the function pointer returned by SDL_GL_GetProcAddress() must be ‘valid’, since the call isn’t crashing. But it appears not to be pointing at ‘genuine’ code (which is returning an invalid string pointer), but probably at a ret which simply leaves the contents of r0 unchanged (GL_VERSION is 0x1F02).

Having patched isAtLeastGL3() to return SDL_FALSE it no longer crashes there (it is still calling glGetStringFunc) but fails later because it can’t create an EGL context. It’s a pity that this causes an abort rather than returning an error from SDL_CreateRenderer(), is that unavoidable?