Ticket #2594 (closed merge: fixed)

Opened 5 years ago

Last modified 5 years ago

Wrong size for Int in arguments to functions wrapped to FunPtr by FFI wrappers (on 64-bit machine)

Reported by: shahn Owned by: igloo
Priority: normal Milestone: 6.10.1
Component: Compiler Version: 6.8.3
Keywords: Cc:
Operating System: Linux Architecture: Unknown/Multiple
Type of failure: Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

An operation

  foo :: Int -> IO ()

is wrapped to a function pointer ptr :: FunPtr (Int -> IO ()) (via an FFI wrapper). If you pass this pointer to a C function, that calls it with a negative parameter (e.g. -1), the operation is executed with a positive parameter (something near 4294967295 ( == 2 ^ 32 - 1)).

This works correctly on x86 (32-bit).

See attachment for an example.

Attachments

FunPtrBug.tar.gz Download (0.5 KB) - added by shahn 5 years ago.

Change History

Changed 5 years ago by shahn

follow-up: ↓ 2   Changed 5 years ago by duncan

  • status changed from new to closed
  • resolution set to invalid

I think this is an incorrect use of the FFI. The example uses Haskell Int and passes it to C code which uses it at C's type int. These are not the same types, though they do happen to coincide on x86 32bit. The example should be using CInt on the Haskell side. Alternatively, if the intention really is to use the Haskell Int type then the C side code must use HsInt (which is defined in HsFFI.h).

The reason we get the observed result is because on x86-64, GHC uses a 64-bit Int while C's int remains 32bit so -1 in a 32bit int is all 1 bits but that bit pattern as a larger int is 2^32-1.

So I'm closing the ticket as invalid. If anyone thinks this is incorrect then please do re-open it.

in reply to: ↑ 1   Changed 5 years ago by shahn

  • status changed from closed to reopened
  • resolution invalid deleted

Replying to duncan:

I was unsure about the correct use of the FFI.

However, the described behavior is also shown when using CInt instead of Int.

I am re-opening the bug...

  Changed 5 years ago by igloo

  • difficulty set to Unknown
  • milestone set to 6.10.1

  Changed 5 years ago by PaulLiu

  • architecture changed from x86_64 (amd64) to Multiple

This bug affects 32-bit machines too if the callback function is made of type: CChar -> IO (), and when C function calls it with -1, it would receive 255 instead.

Functions like rts_mkInt8, rts_mkInt16, etc. in RtsAPI.c would cast values into StgInt after applying a mask. This mask would definitely change the sign of negative numbers. So I wonder why the actual callback into Haskell function would ignore such mask and treat it just like an ordinary StgInt casted back into Int8, Int16, etc.

  Changed 5 years ago by simonmar

  • owner set to simonmar
  • status changed from reopened to new

  Changed 5 years ago by simonmar

  • owner changed from simonmar to igloo
  • type changed from bug to merge

Fixed:

Tue Sep 30 04:56:11 PDT 2008  Simon Marlow <marlowsd@gmail.com>
  * fix #2594: we were erroneously applying masks, as the reporter suggested

  Changed 5 years ago by simonmar

  • architecture changed from Multiple to Unknown/Multiple

  Changed 5 years ago by igloo

  • status changed from new to closed
  • resolution set to fixed

Merged

Note: See TracTickets for help on using tickets.