[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