Miro Karpis | 23 Sep 12:07 2013
Picon

FFI: how to handle external dll crashes

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
Niklas Hambüchen | 23 Sep 13:36 2013

Re: FFI: how to handle external dll crashes

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
Miro Karpis | 23 Sep 14:41 2013
Picon

Re: FFI: how to handle external dll crashes

Hi Niklas,
I think that I'm doing this in my try2 function with tryAny and catchAny functions. Unfortunately that didn't work. I'm just starting with Haskell so maybe also my implementation of my haskell code is not 100% correct.

cheers,
m.


On Mon, Sep 23, 2013 at 1:36 PM, Niklas Hambüchen <mail <at> nh2.me> wrote:
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

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Niklas Hambüchen | 23 Sep 13:46 2013

Re: FFI: how to handle external dll crashes

Hey,

I don't think any of your code actually forks of an *OS process*.

There three main kinds of threading constructs:

* Haskell threads (forkIO)
* Operating System threads (forkOS)
* Operating System processes (forkProcess, fork() in C)

Async uses the first one, you will need last one (which is similar to
effectively start two Haskell programs).

On 23/09/13 20:41, Miro Karpis wrote:
> Hi Niklas,
> I think that I'm doing this in my try2 function with tryAny and catchAny
> functions. Unfortunately that didn't work. I'm just starting with
> Haskell so maybe also my implementation of my haskell code is not 100%
> correct.
Miro Karpis | 23 Sep 15:32 2013
Picon

Re: FFI: how to handle external dll crashes

Thanks for that. I checked forkProcess - which is packed in POSIX module. I'm building under windows. Do I need to go via cygwin, is there some other way for creating new OS process?

m.


On Mon, Sep 23, 2013 at 1:46 PM, Niklas Hambüchen <mail <at> nh2.me> wrote:
Hey,

I don't think any of your code actually forks of an *OS process*.

There three main kinds of threading constructs:

* Haskell threads (forkIO)
* Operating System threads (forkOS)
* Operating System processes (forkProcess, fork() in C)

Async uses the first one, you will need last one (which is similar to
effectively start two Haskell programs).

On 23/09/13 20:41, Miro Karpis wrote:
> Hi Niklas,
> I think that I'm doing this in my try2 function with tryAny and catchAny
> functions. Unfortunately that didn't work. I'm just starting with
> Haskell so maybe also my implementation of my haskell code is not 100%
> correct.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
kudah | 30 Sep 05:15 2013
Picon

Re: FFI: how to handle external dll crashes

On Mon, 23 Sep 2013 15:32:35 +0200 Miro Karpis
<miroslav.karpis <at> gmail.com> wrote:

> Thanks for that. I checked forkProcess - which is packed in POSIX
> module. I'm building under windows. Do I need to go via cygwin, is
> there some other way for creating new OS process?

Windows doesn't support fork(), you'll need to either use cygwin or
move your code to a helper binary and launch it with System.Process.

Gmane