D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 10775 - druntime is not set up to handle dynamically loaded shared libraries in linux
Summary: druntime is not set up to handle dynamically loaded shared libraries in linux
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All Linux
: P2 normal
Assignee: No Owner
URL:
Keywords: dll
Depends on:
Blocks:
 
Reported: 2013-08-08 00:28 UTC by Walter Bright
Modified: 2015-07-24 23:53 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Walter Bright 2013-08-08 00:28:52 UTC
main.d:

    import core.stdc.stdio;
    import core.stdc.stdlib;
    import core.sys.posix.dlfcn;

    extern (C) int dll();

    int main()
    {
        printf("+main()\n");

        void *lh = dlopen("libdll.so", RTLD_LAZY);
        if (!lh)
        {
            fprintf(stderr, "dlopen error: %s\n", dlerror());
            exit(1);
        }
        printf("libdll.so is loaded\n");

        int function() fn = cast(int function())dlsym(lh, "dll");
        char *error = dlerror();
        if (error)
        {
            fprintf(stderr, "dlsym error: %s\n", error);
            exit(1);
        }
        printf("dll() function is found\n");

        fn();

        printf("unloading libdll.so\n");
        dlclose(lh);

        printf("-main()\n");
        return 0;
    }

dll.d:

    import core.stdc.stdio;

    extern (C) int dll()
    {
        printf("dll()\n");
        return 0;
    }

    static this()
    {
        printf("libdll.so construction\n");
    }

    static ~this()
    {
        printf("libdll.so destruction\n");
    }

Build:

    dmd -c dll.d -fPIC
    dmd -oflibdll.so dll.o -shared -defaultlib=libphobos2.so -L-rpath=/home/walter/cbx/mars/phobos/generated/linux/release/64

    dmd -c main.d
    dmd main.o -L-ldl -defaultlib=libphobos2.so -L-rpath=.:/home/walter/cbx/mars/phobos/generated/linux/release/64
    ./main

Results:

    +main()
    libdll.so is loaded
    dll() function is found
    dll()
    unloading libdll.so
    -main()

Note that the module constructors and destructors are not run. This is a bug.
Comment 1 Martin Nowak 2015-07-24 23:53:59 UTC
This was implemented by https://github.com/D-Programming-Language/druntime/pull/593 (https://github.com/D-Programming-Language/druntime/commit/73d067fd04ed8c9588c5ae09ebe48fdb1b528793).

Works for me, I had to change dlopen("libdll.so", RTLD_LAZY) to dlopen("./libdll.so", RTLD_LAZY) though.

+main()
libdll.so construction
libdll.so is loaded
dll() function is found
dll()
unloading libdll.so
libdll.so destruction
-main()

Note: It's better to use Runtime.load/unloadLibrary [¹] instead of dlopen/dlclose b/c then we can run the TLS ctors/dtors without holding the loader lock, thus avoiding a common source of deadlocks and reducing possible contention.

[¹]: http://dlang.org/phobos/core_runtime.html#.Runtime.loadLibrary
rt_loadLibrary or core.runtime.Runtime.loadLibrary.