[HOpenGL] Re: OpenGL/GLUT examples crashing: known problem?

Claus Reinke claus.reinke at talk21.com
Fri Apr 15 13:40:41 EDT 2005


> It's the job of the operating system to ensure that there isn't ;)

configure: checking for OS
configure: result: no :)

thanks for reminding me that the side-effects of this bug shouldn't 
persist on a normal system - sometimes I just take this old system 
too seriously. w98 is not exactly famous for protecting different 
processes from each other's problems.

>If that doesn't work when the OS is doing it implicitly, there's no 
>reason to believe that it would work if the application did it explicitly.

as I mentioned, gdb succeeds on that account, against all reason ;)
 
 it is nice that gdb managed to provide the protection usually
included in an OS, and I wondered whether HOpenGL could offer
the same service. perhaps it isn't worth it, and that part of the problem
will die out with w98, but I thought I'd point out the opportunity.

> .. driver bugs vs library bugs

appart from the driver/os issue, there does seem to be a library bug
in HOpenGL. the C-version of tess exhibits the same symptoms & stack
trace, and the fix is simply to add a stdcall attribute to the callback type. 

So, it seems that HOpenGL on windows/mingw should declare and 
use the GLU callbacks as stdcall, not ccall (or perhaps use APIENTRY,
defined in gl.h?). But I could be wrong about this..

Cheers,
Claus

In some more detail:

from Graphics.Rendering.OpenGL.GLU.Tesselation.hs, an example 
callback:

    type BeginCallback' = GLenum -> IO ()

    withBeginCallback :: TessellatorObj -> BeginCallback -> IO a -> IO a
    withBeginCallback tessObj beginCallback action =
       bracket (makeBeginCallback (beginCallback . unmarshalPrimitiveMode))
               freeHaskellFunPtr $ \callbackPtr -> do
          setBeginCallback tessObj (marshalTessCallback TessBegin) callbackPtr
          action

    foreign import ccall "wrapper" makeBeginCallback ::
       BeginCallback' -> IO (FunPtr BeginCallback')
    
    foreign import CALLCONV unsafe "gluTessCallback" setBeginCallback ::
       TessellatorObj -> GLenum -> FunPtr BeginCallback' -> IO ()

the ccall wrapper looks suspicious to me (btw, where is CALLCONV defined?).

FunPtr (via Base.Foreign.Ptr.hs) leads to Base.GHC.Ptr.lhs, which defines:

    -- Function pointers for the default calling convention.
    data FunPtr a = FunPtr Addr# deriving (Eq, Ord)

I'm not sure where to find the details of mapping between this Haskell type
and its C equivalent, but if I look in my ghc-installation, I find a file 
include/HsFFI.h, which defines:

    typedef void   (*HsFunPtr)(void); /* this should better match StgAddr */

This looks precisely like the callback-type that leads the C-version of tess
to segfault, because the expected type for GLU callbacks happens to be,
from the ghc installation, include/mingw/GL/glu.h:

    typedef void (APIENTRY *_GLUfuncptr)();

where APIENTRY is defined in include/mingw/GL/gl.h as:

    #if !defined(APIENTRY)
    #  if defined(__WIN32__)
    #    define APIENTRY __stdcall
    #  else
    #    define APIENTRY
    #  endif
    #endif

Which seems to be the MS version of the gcc variant I tested with tess.c, 
both variants meaning "callee cleans stack":

    #  define CALLBACK __attribute__ ((__stdcall__))
    void CALLBACK beginCallback(GLenum which)

Note that, if I understand the "wrapper" idea correctly, HOpenGL requests
the callback to be exported as using ccall convention instead.




More information about the HOpenGL mailing list