summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÖmer Sinan Ağacan <omeragacan@gmail.com>2020-04-16 10:32:14 +0300
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-04-18 13:21:44 -0400
commit15ab6cd548f284732a7f89d78c2b89b1bfc4ea1d (patch)
treeb790a245d25d56c170ed8dd1451d52286804ae0a
parente2586828a30202a28dcacac9ab7fc83c43da9e02 (diff)
downloadhaskell-15ab6cd548f284732a7f89d78c2b89b1bfc4ea1d.tar.gz
Improve prepForeignCall error reporting
Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018.
-rw-r--r--libraries/ghci/GHCi/FFI.hsc30
1 files changed, 21 insertions, 9 deletions
diff --git a/libraries/ghci/GHCi/FFI.hsc b/libraries/ghci/GHCi/FFI.hsc
index f88e9e8bd8..74c9e175b1 100644
--- a/libraries/ghci/GHCi/FFI.hsc
+++ b/libraries/ghci/GHCi/FFI.hsc
@@ -58,15 +58,29 @@ prepForeignCall cconv arg_types result_type = do
cif <- mallocBytes (#const sizeof(ffi_cif))
let abi = convToABI cconv
r <- ffi_prep_cif cif abi (fromIntegral n_args) (ffiType result_type) arg_arr
- if (r /= fFI_OK)
- then throwIO (ErrorCall ("prepForeignCallFailed: " ++ show r))
- else return (castPtr cif)
+ if r /= fFI_OK then
+ throwIO $ ErrorCall $ concat
+ [ "prepForeignCallFailed: ", strError r,
+ "(cconv: ", show cconv,
+ " arg tys: ", show arg_types,
+ " res ty: ", show result_type, ")" ]
+ else
+ return (castPtr cif)
freeForeignCallInfo :: Ptr C_ffi_cif -> IO ()
freeForeignCallInfo p = do
free ((#ptr ffi_cif, arg_types) p)
free p
+strError :: C_ffi_status -> String
+strError r
+ | r == fFI_BAD_ABI
+ = "invalid ABI (FFI_BAD_ABI)"
+ | r == fFI_BAD_TYPEDEF
+ = "invalid type description (FFI_BAD_TYPEDEF)"
+ | otherwise
+ = "unknown error: " ++ show r
+
convToABI :: FFIConv -> C_ffi_abi
convToABI FFICCall = fFI_DEFAULT_ABI
#if defined(mingw32_HOST_OS) && defined(i386_HOST_ARCH)
@@ -108,12 +122,10 @@ foreign import ccall "&ffi_type_float" ffi_type_float :: Ptr C_ffi_type
foreign import ccall "&ffi_type_double" ffi_type_double :: Ptr C_ffi_type
foreign import ccall "&ffi_type_pointer"ffi_type_pointer :: Ptr C_ffi_type
-fFI_OK :: C_ffi_status
-fFI_OK = (#const FFI_OK)
---fFI_BAD_ABI :: C_ffi_status
---fFI_BAD_ABI = (#const FFI_BAD_ABI)
---fFI_BAD_TYPEDEF :: C_ffi_status
---fFI_BAD_TYPEDEF = (#const FFI_BAD_TYPEDEF)
+fFI_OK, fFI_BAD_ABI, fFI_BAD_TYPEDEF :: C_ffi_status
+fFI_OK = (#const FFI_OK)
+fFI_BAD_ABI = (#const FFI_BAD_ABI)
+fFI_BAD_TYPEDEF = (#const FFI_BAD_TYPEDEF)
fFI_DEFAULT_ABI :: C_ffi_abi
fFI_DEFAULT_ABI = (#const FFI_DEFAULT_ABI)