[GHC] #13730: Running GLUT code in GHCi yields NSInternalInconsistencyException

GHC ghc-devs at haskell.org
Tue May 23 06:57:55 UTC 2017


#13730: Running GLUT code in GHCi yields NSInternalInconsistencyException
--------------------------------+----------------------------------------
        Reporter:  RyanGlScott  |                Owner:  (none)
            Type:  bug          |               Status:  new
        Priority:  normal       |            Milestone:
       Component:  GHCi         |              Version:  8.0.2
      Resolution:               |             Keywords:
Operating System:  MacOS X      |         Architecture:  Unknown/Multiple
 Type of failure:  GHCi crash   |            Test Case:
      Blocked By:               |             Blocking:
 Related Tickets:               |  Differential Rev(s):
       Wiki Page:               |
--------------------------------+----------------------------------------

Comment (by svenpanne):

 Hmmm,

 taking a step back, the author of a `foreign import` has to answer the
 following questions:

 * Is it OK for the foreign call that (part of) it might run in another OS
 thread?
 * Can the foreign call block?
 * Can the foreign call cause a GC?

 The last item is probably the same question as: Can the foreign call call
 back into Haskell?

 For OpenGL-related calls the answers are:

 * All OpenGL-related code **must** run in a single thread. There is some
 arcane Kung Fu in newer OpenGL revisions to allow a bit of multithreading,
 but it is rarely used and must be done in an explicit manner.
 * The vast majority of OpenGL calls can't block, and even if they can: Due
 to the single thread requirement above, it is OK to block everything.
 * More recent OpenGL versions have the a facility to register debugging
 callbacks which can fire at any time, so basically all OpenGL calls can
 cause a GC.

 All OpenGL calls are done dynamically via native function pointers,
 something like:

 {{{#!haskell
 foreign import ccall "dynamic" dyn376
   :: FunPtr (Ptr a -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ())
   ->         Ptr a -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ()
 }}}

 `safe` is the default, so this should be correct. The GLUT binding is
 basically implemented the same way, with the same restrictions imposed by
 the native API.

 So the bug IMHO in GHCi is that it somehow silently does some thread
 switches behind the scenes, although the original program did not talk
 about multithreading at all. Requiring `runInBoundThread` here doesn't
 seem right.

 I think part of the confusion in this ticket and #8281 is that it is
 highly unclear what `safe` and `unsafe` should actually mean nowadays. In
 the old days, `safe` just meant "Hey, I can call back into Haskell land,
 better take care of your data structures for GC etc.". I have no idea what
 it is supposed to mean in detail today, but it definitely shouldn't be a
 license for thread migration.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13730#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list