www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Shared library: loading doesn't call shared static this

reply "Mathias LANG" <pro.mathias.lang gmail.com> writes:
Hello,
I'm in the process of creating a PAM module using D.

First step, I ported <pam/modules.h> and the included 
pam/_types.h> to D, pretty straightforward.
Then I created a simple D source, which looks like:

````
extern(C) int  pam_sm_open_session(pam_handle_t* pamh, int flags, 
int ac, const char** av)
{
     writeln(__PRETTY_FUNCTION__);
     return PAM_SUCCESS;
}
````

Compiled it using dub, set up PAM & all the required stuff (I've 
already wrote one in C so it was pretty easy), and ran my test 
util, written in C.
I got a SIGSEGV.
I tracked it down to be the writeln call, it seems the fd are not 
initialized.
Easy way to fix it is to call std_stdio_static_this() from 
std.stdiobase.

So I went to http://dlang.org/dll-linux.html , copied the 
example, and here's my result:

xxxx xxxx:~/Work/PAM$ ./main
+main()
Dynamic library is loaded
dll() function is found
dll()
unloading libdll.so
-main()

Which differs from the example in that the "shared static this" 
are not called.
Is that a bug ?

NB: DMD 2.064.2, debian x86_64, gcc 4.8.2
Dec 07 2013
next sibling parent "yazd" <yazan.dabain gmail.com> writes:
On Saturday, 7 December 2013 at 20:11:15 UTC, Mathias LANG wrote:
 Hello,
 I'm in the process of creating a PAM module using D.

 First step, I ported <pam/modules.h> and the included 
 pam/_types.h> to D, pretty straightforward.
 Then I created a simple D source, which looks like:

 ````
 extern(C) int  pam_sm_open_session(pam_handle_t* pamh, int 
 flags, int ac, const char** av)
 {
     writeln(__PRETTY_FUNCTION__);
     return PAM_SUCCESS;
 }
 ````

 Compiled it using dub, set up PAM & all the required stuff 
 (I've already wrote one in C so it was pretty easy), and ran my 
 test util, written in C.
 I got a SIGSEGV.
 I tracked it down to be the writeln call, it seems the fd are 
 not initialized.
 Easy way to fix it is to call std_stdio_static_this() from 
 std.stdiobase.

 So I went to http://dlang.org/dll-linux.html , copied the 
 example, and here's my result:

 xxxx xxxx:~/Work/PAM$ ./main
 +main()
 Dynamic library is loaded
 dll() function is found
 dll()
 unloading libdll.so
 -main()

 Which differs from the example in that the "shared static this" 
 are not called.
 Is that a bug ?

 NB: DMD 2.064.2, debian x86_64, gcc 4.8.2
I believe you'll need to call rt_init() to initialize the d runtime. That will most probably fix the issues you're seeing. http://dlang.org/phobos/core_runtime.html#.rt_init
Dec 07 2013
prev sibling parent reply "Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:
On Saturday, 7 December 2013 at 20:11:15 UTC, Mathias LANG wrote:

afaik, druntime does not officially support the C main, D shared 
library use case yet.

If you have only 1 D shared library, you can insert calls to 
rt_init and rt_term into shared lib constructors/dtors with gcc. 
This has worked for me in pyd:

https://bitbucket.org/ariovistus/pyd/src/32cf9709d711/examples/misc/dmd_sharedlibs/?at=default

You don't want to be calling rt_init or rt_term multiple times, 
though.
Dec 07 2013
parent reply "Mathias LANG" <pro.mathias.lang gmail.com> writes:
On Saturday, 7 December 2013 at 22:55:35 UTC, Ellery Newcomer 
wrote:
 On Saturday, 7 December 2013 at 20:11:15 UTC, Mathias LANG 
 wrote:

 afaik, druntime does not officially support the C main, D 
 shared library use case yet.

 If you have only 1 D shared library, you can insert calls to 
 rt_init and rt_term into shared lib constructors/dtors with 
 gcc. This has worked for me in pyd:

 https://bitbucket.org/ariovistus/pyd/src/32cf9709d711/examples/misc/dmd_sharedlibs/?at=default

 You don't want to be calling rt_init or rt_term multiple times, 
 though.
Thank you, and yazd, it did the trick. May I ask why I don't want to call it multiple time though ? From the sentence "If the runtime was already successfully initialized this returns true.", I though this was handled in some way. Or do you mean, multiple time in case of multiple libraries ?
Dec 08 2013
parent "Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:
On Sunday, 8 December 2013 at 10:31:32 UTC, Mathias LANG wrote:
 Thank you, and yazd, it did the trick.
 May I ask why I don't want to call it multiple time though ?
 From the sentence "If the runtime was already successfully 
 initialized this returns true.", I though this was handled in 
 some way. Or do you mean, multiple time in case of multiple 
 libraries ?
rt_term at least will [did] segfault when you call it a second time. So just don't have N shared libs each with a ctor calling rt_init and dtor calling rt_term.
Dec 08 2013