[Haskell-cafe] FFI: how to handle external dll crashes

Niklas Hambüchen mail at nh2.me
Mon Sep 23 13:36:48 CEST 2013


If you cannot do it with Haskell exceptions, I guess you need to look 
how you would do it in plain C in do the same.

Keep in mind that if something crashes in a C library, that library 
might have corrupted (or leaked) any memory it had access to.

I guess a somewhat reliable way is to fork an OS process, and run your 
crashy DLL in that; if it dies, the OS will keep care of cleaning up 
the low level garbage.

On Mon 23 Sep 2013 17:37:49 SGT, Miro Karpis wrote:
> Please, can you help me with following: I have an external dll that
> I'm importing in my haskell program. In some particular cases the dll
> crashes.
>
> Simplified: first I need to send to dll with MethodA some parameters
> and then call MethodB to do some calculations on those parameters. If
> I didn't give enough parameters then MethodB will crash the whole dll
> and my Haskell application.
>
> Is there a way to handle this? Unfortunately there are no exceptions
> thrown from the dll.
>
> In ghci I'm getting following message: ERROR in
> InitNumericalSystem::initializeSystem. JuncLabel.
>
> I have tried to use "catchAny but that didn't help. c_run is my
> external dll method which takes 4 input parameters:
>
> catchAny :: IO a -> (SomeException -> IO a) -> IO a
> catchAny = Control.Exception.catch
>
> main :: IO ()
> main = do
>   let timeTot = []::[CDouble]
>       timeNow = []::[CDouble]
>       runType = 2::CInt
>   timeTotPtr <- newArray timeTot
>   timeNowPtr <- newArray timeNow
>   result <- (catchAny $ c_run timeTotPtr runType timeNowPtr 0) $ \e -> do
>     putStrLn $ "Got an exception: " ++ show e
>     putStrLn "Returning dummy value of -1"
>     return (-1)
>   free timeTotPtr
>   free timeNowPtr
>   print result
>
>
>
> I have tried also with withAsync, and no luck
>
> tryAny :: IO a -> IO (Either SomeException a)
> tryAny action = withAsync action waitCatch
>
> catchAny :: IO a -> (SomeException -> IO a) -> IO a
> catchAny action onE = tryAny action >>= either onE return
>
> try2 :: IO ()
> try2 = do
>       let timeTot = []::[CDouble]
>           timeNow = []::[CDouble]
>           runType = 2::CInt
>       timeTotPtr <- newArray timeTot
>       timeNowPtr <- newArray timeNow
>       putStrLn $ "c_run going to call c_run.."
>       result <- catchAny (c_run timeTotPtr runType timeNowPtr 0)
> (const $ return (-1))
>       free timeTotPtr
>       free timeNowPtr
>       putStrLn $ "Result: " ++ show result
>
>
> Is there a way how I can handle this?
>
> cheers,
> m.
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list