[Haskell-beginners] FFI to POSIX libc; strerror (errnum); unfreed memory

Folsk Pratima folsk0pratima at cock.li
Fri Apr 12 05:58:19 UTC 2024


I need to turn POSIX errno to the error string.

StrError.hs

import Foreign.C.String
import Foreign.C.Types

foreign import ccall unsafe "strerror" c_strerror :: CInt -> IO CString

strError :: Int -> IO String
strError i = do
    cstr <- c_strerror ci
    peekCAString cstr
  where
    ci = fromIntegral i

main = mapM_ (>>= putStrLn) $ map strError [1 .. 450]


$ ghc -g StrError.hs
$ valgrind --leak-check=full --show-leak-kinds=all ./StrError
==2350== 
==2350== HEAP SUMMARY:
==2350==     in use at exit: 18 bytes in 1 blocks
==2350==   total heap usage: 685 allocs, 684 frees, 97,998 bytes allocated
==2350== 
==2350== 18 bytes in 1 blocks are still reachable in loss record 1 of 1
==2350==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
==2350==    by 0x496A427: __vasprintf_internal (vasprintf.c:71)
==2350==    by 0x493DBD5: asprintf (asprintf.c:31)
==2350==    by 0x498A9F0: strerror_l (strerror_l.c:45)
==2350==    by 0x408BC0: ??? (StrError.hs:8)
==2350== 
==2350== LEAK SUMMARY:
==2350==    definitely lost: 0 bytes in 0 blocks
==2350==    indirectly lost: 0 bytes in 0 blocks
==2350==      possibly lost: 0 bytes in 0 blocks
==2350==    still reachable: 18 bytes in 1 blocks
==2350==         suppressed: 0 bytes in 0 blocks
==2350== 
==2350== For lists of detected and suppressed errors, rerun with: -s
==2350== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


I am already frustrated with having to use IO for this. I feel like it
is better to manually create a pure solution by copying whatever the C
code from libc does.

But I still do not understand what causes this memory to remain
reachable. Calling strerror from pure C code does not leave reachable
memory regions.

Can anyone explain? And maybe you have a suggestion as to how to
implement this strError function properly?

Just in case you are the type of a person to inquire as to *why* I need
this, for fun. I need it for fun.


More information about the Beginners mailing list