How to best deal with nullPtr from alloca and friends?

I was reading up on the documentation for alloca and friends[1], which says, "If any of the allocation functions fails, a value of nullPtrhttp://www.haskell.org/ghc/docs/7.0.2/html/libraries/base-4.3.1.0/Foreign-Pt... is produced." It seems like every example of FFI code that I find which uses alloca ignores the possibility of a nullPtr[2, 3, 4]. So then I started trying out examples with the help of dmwit and others from #haskell. It seems that actually, alloca and friends throw exceptions: dmwit> main = allocaArray (2^30) (\ptr -> print ((nullPtr :: Ptr Double) == ptr)) <dmwit> lispy: alloca also throws an exception. <dmwit> lispy: Or rather, allocaBytes throws an exception, and alloca is implemented in terms of allocaBytes, so I'm *guessing* that alloca throws an exception. I'm on a 64bit version of windows here with more than 4GB of memory to spare for the GHC process. Unfortunately, allocaBytes takes an Int so I can't test it with a request larger than the amount of physical ram I have. Just playing around with different arguments to allocaBytes I can get different behavior: <= 2^30 bytes, works perfectly == 2^30 + 2^20 bytes, I get an "<interactive>: out of memory" message and ghci terminates == 2^31-1, I get a crash where windows pops up a little dialog saying my program (ghci) has crashed. The behavior seems to be inconsistent with the documentation. What is the correct behavior for alloca and friends and should I be checking for nullPtr? Thanks, Jason [1] http://www.haskell.org/ghc/docs/7.0.2/html/libraries/base-4.3.1.0/Foreign-Ma... [2] http://en.wikibooks.org/wiki/Haskell/FFI [3] http://www.haskell.org/haskellwiki/HSFFIG/Examples [4] http://book.realworldhaskell.org/read/interfacing-with-c-the-ffi.html

On Mon, Mar 28, 2011 at 9:43 PM, Jason Dagit
I'm on a 64bit version of windows here with more than 4GB of memory to spare
for the GHC process. Unfortunately, allocaBytes takes an Int so I can't test it with a request larger than the amount of physical ram I have.
It would seem that the Haskell Platform for windows only ships a 32 bit binary. That is rather unfortunate: $ ghci +RTS --info WARNING: GHCi invoked via 'ghci.exe' in *nix-like shells (cygwin-bash, in partic ular) doesn't handle Ctrl-C well; use the 'ghcii.sh' shell wrapper instead [("GHC RTS", "YES") ,("GHC version", "7.0.2") ,("RTS way", "rts_thr") ,("Build platform", "i386-unknown-mingw32") ,("Build architecture", "i386") ,("Build OS", "mingw32") ,("Build vendor", "unknown") ,("Host platform", "i386-unknown-mingw32") ,("Host architecture", "i386") ,("Host OS", "mingw32") ,("Host vendor", "unknown") ,("Target platform", "i386-unknown-mingw32") ,("Target architecture", "i386") ,("Target OS", "mingw32") ,("Target vendor", "unknown") ,("Word size", "32") ,("Compiler unregisterised", "NO") ,("Tables next to code", "YES") ] With a 64bit build, perhaps I could experiment more. I looked at the Haskell Platform page and I don't see a 64bit version. It would seem the binary from GHC HQ has the same limitation since there is only one installer and it claims to work on windows 2000: http://www.haskell.org/ghc/download_ghc_7_0_3#windows Jason

Excerpts from Jason Dagit's message of Tue Mar 29 00:43:10 -0400 2011:
I was reading up on the documentation for alloca and friends[1], which says, "If any of the allocation functions fails, a value of nullPtrhttp://www.haskell.org/ghc/docs/7.0.2/html/libraries/base-4.3.1.0/Foreign-Pt... is produced."
It seems like every example of FFI code that I find which uses alloca ignores the possibility of a nullPtr[2, 3, 4].
So then I started trying out examples with the help of dmwit and others from #haskell.
It seems that actually, alloca and friends throw exceptions: dmwit> main = allocaArray (2^30) (\ptr -> print ((nullPtr :: Ptr Double) == ptr)) <dmwit> lispy: alloca also throws an exception. <dmwit> lispy: Or rather, allocaBytes throws an exception, and alloca is implemented in terms of allocaBytes, so I'm *guessing* that alloca throws an exception.
I'm on a 64bit version of windows here with more than 4GB of memory to spare for the GHC process. Unfortunately, allocaBytes takes an Int so I can't test it with a request larger than the amount of physical ram I have.
You could try testing by setting different limits on the memory usage of your process with ulimit. I'll give a test, but the prevailing wisdom is that if you OOM, you're really out of luck. Edward

On Tue, Mar 29, 2011 at 2:37 AM, Edward Z. Yang
Excerpts from Jason Dagit's message of Tue Mar 29 00:43:10 -0400 2011:
I was reading up on the documentation for alloca and friends[1], which says, "If any of the allocation functions fails, a value of nullPtr< http://www.haskell.org/ghc/docs/7.0.2/html/libraries/base-4.3.1.0/Foreign-Pt...
is produced."
It seems like every example of FFI code that I find which uses alloca ignores the possibility of a nullPtr[2, 3, 4].
So then I started trying out examples with the help of dmwit and others from #haskell.
It seems that actually, alloca and friends throw exceptions: dmwit> main = allocaArray (2^30) (\ptr -> print ((nullPtr :: Ptr Double) == ptr)) <dmwit> lispy: alloca also throws an exception. <dmwit> lispy: Or rather, allocaBytes throws an exception, and alloca is implemented in terms of allocaBytes, so I'm *guessing* that alloca throws an exception.
I'm on a 64bit version of windows here with more than 4GB of memory to spare for the GHC process. Unfortunately, allocaBytes takes an Int so I can't test it with a request larger than the amount of physical ram I have.
You could try testing by setting different limits on the memory usage of your process with ulimit. I'll give a test, but the prevailing wisdom is that if you OOM, you're really out of luck.
I just want to be clear: You can get alloca and friends to fail well BEFORE you are OOM. Just allocate something larger than the remaining contiguous space. If you're allocating a few KB and you run out of memory that can be bad situation, but I don't think we should treat all allocation failures as if the sky is falling :) Jason
participants (2)
-
Edward Z. Yang
-
Jason Dagit