[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