Thread overview
Shared library: loading doesn't call shared static this
Dec 07, 2013
Mathias LANG
Dec 07, 2013
yazd
Dec 07, 2013
Ellery Newcomer
Dec 08, 2013
Mathias LANG
Dec 08, 2013
Ellery Newcomer
December 07, 2013
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
December 07, 2013
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
December 07, 2013
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.
December 08, 2013
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 ?
December 08, 2013
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.