Segfault when doing hs_init()/hs_exit() multiple times

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Segfault when doing hs_init()/hs_exit() multiple times

Alp Mestanogullari
Hello everyone,

I'm currently calling Haskell code from C. My goal is to apply a Haskell function to each element of some dataset that I get from outside Haskell-land. For now, before I make this fancier and more efficient, the plan is to just bring the RTS up with hs_init, call my Haskell function (exporter to C with 'foreign export ccall [...]') on the element and finally shut the RTS down, doing this for every element.

When running this, I realized the RTS was running into a segfault when calling the Haskell function on the second element. This led me to believe it wasn't possible to call hs_init()/hs_exit() multiple times in the same program. But then I checked the Haskell 2010 report, FFI section [1], and it says:

The function hs_init() initialises the Haskell system and provides it with the available command line arguments. Upon return, the arguments solely intended for the Haskell runtime system are removed (i.e., the values that argc and argv point to may have changed). This function must be called during program startup before any Haskell function is invoked; otherwise, the system behaviour is undefined. Conversely, the Haskell system is deinitialised by a call to hs_exit(). Multiple invocations of hs_init() are permitted, provided that they are followed by an equal number of calls to hs_exit() and that the first call to hs_exit() is after the last call to hs_init(). In addition to nested calls to hs_init(), the Haskell system may be de-initialised with hs_exit() and be re-initialised with hs_init() at a later point in time. This ensures that repeated initialisation due to multiple libraries being implemented in Haskell is covered.

Which means, if I understand correctly, that what I want, while very inefficient, should work fine.

I've put together a minimal example that exhibits the problem, which can be found at https://github.com/alpmestan/simple-c-export :

- https://github.com/alpmestan/simple-c-export/blob/master/run-haskell.c shows the C code that brings the RTS up and down, with some printf statements to show what's going on.

- https://github.com/alpmestan/simple-c-export/blob/master/Foo.hs shows the trivial Haskell function I'm exposing.

- https://github.com/alpmestan/simple-c-export/blob/master/simple-c-export.cabal contains the build options I'm compiling the code with

When running this on my machine (OS X, ghc 7.8.3 and 7.10.2), I always get:

$ cabal run simple-c
Preprocessing executable 'simple-c' for simple-c-export-0.1...
Linking dist/build/simple-c/simple-c ...
Running simple-c...
#0 - Launching RTS...
#0 - RTS started! Calling Haskell function...
0
#0 - Killing RTS now...
#0 - RTS killed!
#1 - Launching RTS...
#1 - RTS started! Calling Haskell function...
Segmentation fault: 11

Is there something special I should do to make this work, that I'm overlooking? Or is this a bug (that I should report on Trac, I guess) ?

Thanks in advance for any clarification on this.

--
Alp Mestanogullari

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: Segfault when doing hs_init()/hs_exit() multiple times

Karl Cronburg
I was having the same problem a while back. If you turn on debugging symbols and give it to gdb, you
get that the seg fault is happening when the RTS attempts to allocate after the second initialization:

    Program received signal SIGSEGV, Segmentation fault.
    0xf7f6f4f9 in allocate (cap=cap@entry=0xf7f92b40 <MainCapability>, n=n@entry=2) at rts/sm/Storage.c:812
    812 rts/sm/Storage.c: No such file or directory.
    (gdb) bt
    #0  0xf7f6f4f9 in allocate (cap=cap@entry=0xf7f92b40 <MainCapability>, n=n@entry=2) at rts/sm/Storage.c:812
    #1  0xf7f5c603 in rts_mkInt32 (cap=0xf7f92b40 <MainCapability>, i=-11921) at rts/RtsAPI.c:69
    #2  0xf7cdea7a in pointer_test () from ../../ia32/build/libHSpads-haskell-1.1-6fKCdLtCMO82em71etbiu1-ghc7.10.2.so
    #3  0x5655579c in main (argc=1, argv=0xffffd244) at Pointer.c:11

So my solution was to just leave the RTS initialized. What's the downside of leaving it initialized throughout
the entire execution of your program? If the RTS / GC is smart enough it should know not to waste time
doing a GC when no Haskell code has been run?

I too would be interested though in being able to clean up the RTS from C when I know no Haskell code will
be run again anytime soon.

-Karl Cronburg-

On Wed, Dec 2, 2015 at 1:58 PM, Alp Mestanogullari <[hidden email]> wrote:
Hello everyone,

I'm currently calling Haskell code from C. My goal is to apply a Haskell function to each element of some dataset that I get from outside Haskell-land. For now, before I make this fancier and more efficient, the plan is to just bring the RTS up with hs_init, call my Haskell function (exporter to C with 'foreign export ccall [...]') on the element and finally shut the RTS down, doing this for every element.

When running this, I realized the RTS was running into a segfault when calling the Haskell function on the second element. This led me to believe it wasn't possible to call hs_init()/hs_exit() multiple times in the same program. But then I checked the Haskell 2010 report, FFI section [1], and it says:

The function hs_init() initialises the Haskell system and provides it with the available command line arguments. Upon return, the arguments solely intended for the Haskell runtime system are removed (i.e., the values that argc and argv point to may have changed). This function must be called during program startup before any Haskell function is invoked; otherwise, the system behaviour is undefined. Conversely, the Haskell system is deinitialised by a call to hs_exit(). Multiple invocations of hs_init() are permitted, provided that they are followed by an equal number of calls to hs_exit() and that the first call to hs_exit() is after the last call to hs_init(). In addition to nested calls to hs_init(), the Haskell system may be de-initialised with hs_exit() and be re-initialised with hs_init() at a later point in time. This ensures that repeated initialisation due to multiple libraries being implemented in Haskell is covered.

Which means, if I understand correctly, that what I want, while very inefficient, should work fine.

I've put together a minimal example that exhibits the problem, which can be found at https://github.com/alpmestan/simple-c-export :

- https://github.com/alpmestan/simple-c-export/blob/master/run-haskell.c shows the C code that brings the RTS up and down, with some printf statements to show what's going on.

- https://github.com/alpmestan/simple-c-export/blob/master/Foo.hs shows the trivial Haskell function I'm exposing.

- https://github.com/alpmestan/simple-c-export/blob/master/simple-c-export.cabal contains the build options I'm compiling the code with

When running this on my machine (OS X, ghc 7.8.3 and 7.10.2), I always get:

$ cabal run simple-c
Preprocessing executable 'simple-c' for simple-c-export-0.1...
Linking dist/build/simple-c/simple-c ...
Running simple-c...
#0 - Launching RTS...
#0 - RTS started! Calling Haskell function...
0
#0 - Killing RTS now...
#0 - RTS killed!
#1 - Launching RTS...
#1 - RTS started! Calling Haskell function...
Segmentation fault: 11

Is there something special I should do to make this work, that I'm overlooking? Or is this a bug (that I should report on Trac, I guess) ?

Thanks in advance for any clarification on this.

--
Alp Mestanogullari

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users



_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: Segfault when doing hs_init()/hs_exit() multiple times

Karl Cronburg
Upon further investigation:

    "The FFI spec requires the implementation to support re-initialising itself after being shut down with hs_exit(), but GHC does not currently support that."

So it's a known issue / shortcoming.

-Karl Cronburg-

On Wed, Dec 2, 2015 at 2:41 PM, Karl Cronburg <[hidden email]> wrote:
I was having the same problem a while back. If you turn on debugging symbols and give it to gdb, you
get that the seg fault is happening when the RTS attempts to allocate after the second initialization:

    Program received signal SIGSEGV, Segmentation fault.
    0xf7f6f4f9 in allocate (cap=cap@entry=0xf7f92b40 <MainCapability>, n=n@entry=2) at rts/sm/Storage.c:812
    812 rts/sm/Storage.c: No such file or directory.
    (gdb) bt
    #0  0xf7f6f4f9 in allocate (cap=cap@entry=0xf7f92b40 <MainCapability>, n=n@entry=2) at rts/sm/Storage.c:812
    #1  0xf7f5c603 in rts_mkInt32 (cap=0xf7f92b40 <MainCapability>, i=-11921) at rts/RtsAPI.c:69
    #2  0xf7cdea7a in pointer_test () from ../../ia32/build/libHSpads-haskell-1.1-6fKCdLtCMO82em71etbiu1-ghc7.10.2.so
    #3  0x5655579c in main (argc=1, argv=0xffffd244) at Pointer.c:11

So my solution was to just leave the RTS initialized. What's the downside of leaving it initialized throughout
the entire execution of your program? If the RTS / GC is smart enough it should know not to waste time
doing a GC when no Haskell code has been run?

I too would be interested though in being able to clean up the RTS from C when I know no Haskell code will
be run again anytime soon.

-Karl Cronburg-

On Wed, Dec 2, 2015 at 1:58 PM, Alp Mestanogullari <[hidden email]> wrote:
Hello everyone,

I'm currently calling Haskell code from C. My goal is to apply a Haskell function to each element of some dataset that I get from outside Haskell-land. For now, before I make this fancier and more efficient, the plan is to just bring the RTS up with hs_init, call my Haskell function (exporter to C with 'foreign export ccall [...]') on the element and finally shut the RTS down, doing this for every element.

When running this, I realized the RTS was running into a segfault when calling the Haskell function on the second element. This led me to believe it wasn't possible to call hs_init()/hs_exit() multiple times in the same program. But then I checked the Haskell 2010 report, FFI section [1], and it says:

The function hs_init() initialises the Haskell system and provides it with the available command line arguments. Upon return, the arguments solely intended for the Haskell runtime system are removed (i.e., the values that argc and argv point to may have changed). This function must be called during program startup before any Haskell function is invoked; otherwise, the system behaviour is undefined. Conversely, the Haskell system is deinitialised by a call to hs_exit(). Multiple invocations of hs_init() are permitted, provided that they are followed by an equal number of calls to hs_exit() and that the first call to hs_exit() is after the last call to hs_init(). In addition to nested calls to hs_init(), the Haskell system may be de-initialised with hs_exit() and be re-initialised with hs_init() at a later point in time. This ensures that repeated initialisation due to multiple libraries being implemented in Haskell is covered.

Which means, if I understand correctly, that what I want, while very inefficient, should work fine.

I've put together a minimal example that exhibits the problem, which can be found at https://github.com/alpmestan/simple-c-export :

- https://github.com/alpmestan/simple-c-export/blob/master/run-haskell.c shows the C code that brings the RTS up and down, with some printf statements to show what's going on.

- https://github.com/alpmestan/simple-c-export/blob/master/Foo.hs shows the trivial Haskell function I'm exposing.

- https://github.com/alpmestan/simple-c-export/blob/master/simple-c-export.cabal contains the build options I'm compiling the code with

When running this on my machine (OS X, ghc 7.8.3 and 7.10.2), I always get:

$ cabal run simple-c
Preprocessing executable 'simple-c' for simple-c-export-0.1...
Linking dist/build/simple-c/simple-c ...
Running simple-c...
#0 - Launching RTS...
#0 - RTS started! Calling Haskell function...
0
#0 - Killing RTS now...
#0 - RTS killed!
#1 - Launching RTS...
#1 - RTS started! Calling Haskell function...
Segmentation fault: 11

Is there something special I should do to make this work, that I'm overlooking? Or is this a bug (that I should report on Trac, I guess) ?

Thanks in advance for any clarification on this.

--
Alp Mestanogullari

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users




_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
Reply | Threaded
Open this post in threaded view
|

Re: Segfault when doing hs_init()/hs_exit() multiple times

Alp Mestanogullari
Oh, this page didn't pop up during my googling, earlier. Thanks! I guess I'll just arrange for the RTS to be initialized and shutdown only once. I'd love to know why GHC decided to diverge from the Report on this, if anyone knows.

On Wed, Dec 2, 2015 at 8:58 PM, Karl Cronburg <[hidden email]> wrote:
Upon further investigation:

    "The FFI spec requires the implementation to support re-initialising itself after being shut down with hs_exit(), but GHC does not currently support that."

So it's a known issue / shortcoming.

-Karl Cronburg-

On Wed, Dec 2, 2015 at 2:41 PM, Karl Cronburg <[hidden email]> wrote:
I was having the same problem a while back. If you turn on debugging symbols and give it to gdb, you
get that the seg fault is happening when the RTS attempts to allocate after the second initialization:

    Program received signal SIGSEGV, Segmentation fault.
    0xf7f6f4f9 in allocate (cap=cap@entry=0xf7f92b40 <MainCapability>, n=n@entry=2) at rts/sm/Storage.c:812
    812 rts/sm/Storage.c: No such file or directory.
    (gdb) bt
    #0  0xf7f6f4f9 in allocate (cap=cap@entry=0xf7f92b40 <MainCapability>, n=n@entry=2) at rts/sm/Storage.c:812
    #1  0xf7f5c603 in rts_mkInt32 (cap=0xf7f92b40 <MainCapability>, i=-11921) at rts/RtsAPI.c:69
    #2  0xf7cdea7a in pointer_test () from ../../ia32/build/libHSpads-haskell-1.1-6fKCdLtCMO82em71etbiu1-ghc7.10.2.so
    #3  0x5655579c in main (argc=1, argv=0xffffd244) at Pointer.c:11

So my solution was to just leave the RTS initialized. What's the downside of leaving it initialized throughout
the entire execution of your program? If the RTS / GC is smart enough it should know not to waste time
doing a GC when no Haskell code has been run?

I too would be interested though in being able to clean up the RTS from C when I know no Haskell code will
be run again anytime soon.

-Karl Cronburg-

On Wed, Dec 2, 2015 at 1:58 PM, Alp Mestanogullari <[hidden email]> wrote:
Hello everyone,

I'm currently calling Haskell code from C. My goal is to apply a Haskell function to each element of some dataset that I get from outside Haskell-land. For now, before I make this fancier and more efficient, the plan is to just bring the RTS up with hs_init, call my Haskell function (exporter to C with 'foreign export ccall [...]') on the element and finally shut the RTS down, doing this for every element.

When running this, I realized the RTS was running into a segfault when calling the Haskell function on the second element. This led me to believe it wasn't possible to call hs_init()/hs_exit() multiple times in the same program. But then I checked the Haskell 2010 report, FFI section [1], and it says:

The function hs_init() initialises the Haskell system and provides it with the available command line arguments. Upon return, the arguments solely intended for the Haskell runtime system are removed (i.e., the values that argc and argv point to may have changed). This function must be called during program startup before any Haskell function is invoked; otherwise, the system behaviour is undefined. Conversely, the Haskell system is deinitialised by a call to hs_exit(). Multiple invocations of hs_init() are permitted, provided that they are followed by an equal number of calls to hs_exit() and that the first call to hs_exit() is after the last call to hs_init(). In addition to nested calls to hs_init(), the Haskell system may be de-initialised with hs_exit() and be re-initialised with hs_init() at a later point in time. This ensures that repeated initialisation due to multiple libraries being implemented in Haskell is covered.

Which means, if I understand correctly, that what I want, while very inefficient, should work fine.

I've put together a minimal example that exhibits the problem, which can be found at https://github.com/alpmestan/simple-c-export :

- https://github.com/alpmestan/simple-c-export/blob/master/run-haskell.c shows the C code that brings the RTS up and down, with some printf statements to show what's going on.

- https://github.com/alpmestan/simple-c-export/blob/master/Foo.hs shows the trivial Haskell function I'm exposing.

- https://github.com/alpmestan/simple-c-export/blob/master/simple-c-export.cabal contains the build options I'm compiling the code with

When running this on my machine (OS X, ghc 7.8.3 and 7.10.2), I always get:

$ cabal run simple-c
Preprocessing executable 'simple-c' for simple-c-export-0.1...
Linking dist/build/simple-c/simple-c ...
Running simple-c...
#0 - Launching RTS...
#0 - RTS started! Calling Haskell function...
0
#0 - Killing RTS now...
#0 - RTS killed!
#1 - Launching RTS...
#1 - RTS started! Calling Haskell function...
Segmentation fault: 11

Is there something special I should do to make this work, that I'm overlooking? Or is this a bug (that I should report on Trac, I guess) ?

Thanks in advance for any clarification on this.

--
Alp Mestanogullari

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users






--
Alp Mestanogullari

_______________________________________________
Glasgow-haskell-users mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users