Skip to content

GHCi segmentation fault when use readv system call

Summary

Error occur when calling system call readv and writev in GHCi.

Steps to reproduce

TryVectoredIo.hsc

{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module TryVectoredIo (tryWritev, tryReadv) where

import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable(..))
import Foreign.Marshal (alloca, allocaBytes)
import Foreign.C.Types (CInt(..), CChar)
import Foreign.C.String (peekCStringLen, withCStringLen)
import Control.Exception (bracket)
import Data.Int (Int64)
import System.Posix (
	Fd(..), FileMode, openFd, createFile, closeFd,
	OpenMode(..), defaultFileFlags,
	unionFileModes,
	ownerReadMode, ownerWriteMode, groupReadMode, otherReadMode )

#include <sys/uio.h>

foreign import ccall "readv"
	c_readv :: Fd -> Ptr Iovec -> CInt -> IO #type ssize_t

tryReadv :: IO ()
tryReadv = withOpenReadModeFd "foo.txt" $ \fd ->
	allocaBytes 5 $ \pc -> alloca $ \piov -> do
		poke piov $ Iovec (pc, 5)
		print =<< c_readv fd piov 1
		print =<< peekCStringLen (pc, 5)

withOpenReadModeFd :: FilePath -> (Fd -> IO a) -> IO a
withOpenReadModeFd fp =
	bracket (openFd fp ReadOnly Nothing defaultFileFlags) closeFd

tryWritev :: IO ()
tryWritev = withCreateFile "foo.txt" fm644 $ \fd ->
	withCStringLen "hello" $ \(pc, ln) -> alloca $ \piov -> do
		poke piov $ Iovec (pc, fromIntegral ln)
		print =<< c_writev fd piov 1

foreign import ccall "writev"
	c_writev :: Fd -> Ptr Iovec -> CInt -> IO #type ssize_t

newtype {-# CTYPE "sys/uio.h" "struct iovec" #-} Iovec = Iovec (Ptr CChar, CInt) deriving Show

instance Storable Iovec where
	sizeOf _ = #size struct iovec
	alignment _ = #alignment struct iovec
	peek p = Iovec <$> ((,) <$> #{peek struct iovec, iov_base} p <*> #{peek struct iovec, iov_len} p)
	poke p (Iovec (pc, n)) = #{poke struct iovec, iov_base} p pc >> #{poke struct iovec, iov_len} p n

withCreateFile :: FilePath -> FileMode -> (Fd -> IO a) -> IO a
withCreateFile fp fm = bracket (createFile fp fm) closeFd

fm644 :: FileMode
fm644 = foldr1 unionFileModes
	[ownerReadMode, ownerWriteMode, groupReadMode, otherReadMode]
% hsc2hs --version
hsc2hs version 0.68.1
% hsc2hs mydir/TryVectoredIO.hsc
% ./inplace/bin/ghc-stage2 --version
The Glorious Glasgow Haskell Compilation System, version 8.9.0.20190909
% ./inplace/bin/ghc-stage2 --interactive mydir/TryVectoredIO.hs
> tryWritev
20873216
> tryWritev
46202880
> tryReadv
-1
"Ew"
> tryReadv
zsh: segmentation fault ...
% ./inplace/bin/ghc-stage2 --interactive mydir/TryVectoredIO.hs
> tryWritev
54775808
> tryReadv
<intractive>: internal error: stg_ap_pv_ret
    (GHC version 8.9.0.20190909 for x86_64_unknown_linux)
    Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
zsh: abort ./inplace/bin/ghc-stage2 --interactive mydir/TryVectoredIo.hs
% ./inplace/bin/ghc-stage2 --interactive mydir/TryVectoredIO.hs
> tryWritev
21291008
> tryReadv
zsh: segmentation fault ...
% ls -l foo.txt
-rw-r--r-- 1 bar baz 21291008 Sep 11 17:59 foo.txt

Expected behavior

% ./inplace/bin/ghc-stage2 --interactive mydir/TryVectoredIO.hs
> tryWritev
5
> tryReadv
5
"hello"
> :quit
% cat foo.txt
hello

Environment

  • GHC version used: The Glorious Glasgow Haskell Compilation System, version 8.9.0.20190909
  • gcc version used: gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0
  • glibc version used: 2.29-r2
  • hsc2hs version used: 0.68.1
  • OS version used: Linux version 4.19.66-gentoo

Optional:

  • Operating System: Gentoo GNU/Linux
  • System Architecture:
Edited by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information