[GHC] #8281: The impossible happened: primRepToFFIType

GHC ghc-devs
Fri Oct 4 17:39:01 UTC 2013


#8281: The impossible happened: primRepToFFIType
---------------------------------------+-----------------------------------
        Reporter:  tibbe               |            Owner:
            Type:  bug                 |           Status:  new
        Priority:  normal              |        Milestone:
       Component:  Compiler            |          Version:  7.6.2
      Resolution:                      |         Keywords:
Operating System:  Unknown/Multiple    |     Architecture:
 Type of failure:  Compile-time crash  |  Unknown/Multiple
       Test Case:                      |       Difficulty:  Unknown
        Blocking:                      |       Blocked By:
                                       |  Related Tickets:
---------------------------------------+-----------------------------------
Changes (by simonpj):

 * cc: simonmar (added)


Comment:

 I see what is happening here, but need help from Simon M or anyone else.
 Here's what I learned:

 * `ThreadId#` is represented by a heap pointer; it's "rep" is `PtrRep`.
 But it is a primitive type; i.e. not implemented in Haskell.

 * The totally-undocumented flag `-XUnliftedFFITypes` seems to allow all of
 GHC's primitive types to be marshalled across the FFI.

 * These primitive types include `Array#`, `MutableArray#`, `ByteArray#`
 and `MutableByteArray#`, all of which also have `PtrRep`.

 * Marshalling these pointer types seems utterly wrong for a '''safe'''
 call, where GC might occur during the call, thereby moving the array.  (Or
 maybe arrays never move?  If so, this is un-documented.)

 * The actual crash comes in `LibFFI.hsc`, in `primRepToFFIType` which is
 used (via `prepForeignCall`) only by the bytecode generator, to prepare
 the foreign call arguments.  `primRepToFFIType` barfs if it gets a
 `PtrRep`.

 * How does it work for `Array#` and friends?  Because have a special shim
 in `ByteCodeGen.generateCCall`, which adds an offset to get past the array
 header, and then says `AddrRep`!  Hence `primRepToFFIType` sees an
 `AddrRep`.

 * There is no such special treatment for `ThreadId#`, hence the crash.

 * The base-library module `GHC.Conc.Sync` has precisely the
 `rts_getThreadId` import as in the tiny test case above, but works(just)
 because it is compiled.

 My conclusion:

 * These `PtrRep` things should not be allowed in '''safe''' foreign calls.
 * In `primRepToFFIType` we should allow `PtrRep`

 However I'm not certain about the last of these because I don't understand
 how foreign calls work in the bytecode interpreter.

 Simon M: do you agree?

 Simon

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



More information about the ghc-tickets mailing list