Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when dlopen'ed library not dlclose'd explicitly #17475

Open
dlangBugzillaToGithub opened this issue Mar 1, 2024 · 13 comments
Open

Crash when dlopen'ed library not dlclose'd explicitly #17475

dlangBugzillaToGithub opened this issue Mar 1, 2024 · 13 comments
Labels
Arch:x86_64 Issues specific to x86_64 Druntime Specific to druntime OS:Linux P1 Severity:major

Comments

@dlangBugzillaToGithub
Copy link

Carl Sturtivant reported this on 2024-03-01T20:35:03Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=24427

CC List

  • Richard (Rikki) Andrew Cattermole

Description

Compiling pure C (no D source) with dmd and using dynamic loading (not dynamic linking) causes a crash on program exit under certain conditions, where a gcc compilation of the same source works fine.

Rewriting the C in D and compiling with dmd with identical switches causes the same crash.

The following two examples are attached, using dlfcn.h from C source and core.sys.posix.dlfcn from D source. Both crash.

A.
====
dmd -c main.c
dmd -of=main -L-E main.o -L-ldl

dmd -c -fPIC dynamic_lib.c
dmd -of=dynamic_lib.so -shared -fPIC dynamic_lib.o
====

B.
====
dmd -c main.d
dmd -of=main -L-E main.o -L-ldl

dmd -c -fPIC dynamic_lib.d
dmd -of=dynamic_lib.so -shared -fPIC dynamic_lib.o
====

A. and B.
* main dynamically loads dynamic_lib.so
* main calls a function in dynamic_lib.so which calls a function in main
* main is linked with a switch to export all symbols so this works

When A. is built with gcc it works fine.

Failure to call dlclose before main exits causes the crash; main runs correctly before that. (If the commented out call of dlclose is made then everything works.)

Crash:
====
$ main
1
2
3
4
Aborting from src/rt/sections_elf_shared.d(512) DSO being unregistered isn't current last one.Aborted (core dumped)
====

This crash occurs only if

1.
Both main and dynamic_lib are built with dmd.
(either from C source or D source)
(If one of main, dynamic_lib.so is built with gcc, everything works.)

2.
Main is NOT linked with -defaultlib=libphobos2.so
(irrespective of how dynamic_lib is linked to phobos)

!!!There are attachements in the bugzilla issue that have not been copied over!!!

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T20:37:14Z

Created attachment 1907
main.c

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T20:37:54Z

Created attachment 1908
dynamic_lib.c

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T20:38:43Z

Created attachment 1909
main.d

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T20:39:15Z

Created attachment 1910
dynamic_lib.d

@dlangBugzillaToGithub
Copy link
Author

alphaglosined commented on 2024-03-01T20:51:38Z

Just to clarify:

Does a crash only occur when the executable has druntime linked in and initialized?

If you load a shared library that has druntime linked in, does it also crash if you initialize druntime?

Does this happen with ldc?

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T21:50:35Z

1.
lcd did not produce the bug, using --link-defaultlib-shared=false for both the main program and the dynamic library.

2.
When the dynamic library C source is compiled and linked with -betterC the error does not occur.

3.
It does crash with druntime initialized in the dynamic library.

@dlangBugzillaToGithub
Copy link
Author

alphaglosined commented on 2024-03-01T21:54:15Z

When using ldc does it crash when druntime is a shared library and initialized?

This will confirm that it is a druntime bug.

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T22:01:52Z

> When using ldc does it crash when druntime is a shared library and initialized?

Is this the default for ldc?

@dlangBugzillaToGithub
Copy link
Author

alphaglosined commented on 2024-03-01T22:06:05Z

The default phobos/druntime shared/static may depend upon platform and distribution.

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T22:54:36Z

(In reply to Richard Cattermole from comment #9)
> The default phobos/druntime shared/static may depend upon platform and
> distribution.

I used the --link-defaultlib-shared=true option which I assume also shares druntime. I found no switch mentioning sharing or statically linking druntime explicitly.

Neither main.c nor dynamic_lib.c will link with --link-defaultlib-shared=true
With that false, the C version just works.

By contrast, D source links for all four combinations of true/false for --link-defaultlib-shared for each build. Three work, one crashes.
====
$ ldc2 -c main.d
$ ldc2 -of=main -L-E main.o -L-ldl --link-defaultlib-shared=false
$ ldc2 -c --relocation-model=pic dynamic_lib.d
$ + ldc2 -of=dynamic_lib.so -shared -relocation-model=pic dynamic_lib.o --link-defaultlib-shared=true
$ main
Aborting from rt/sections_elf_shared.d(605) Only one D shared object allowed for static runtime. Link with shared runtime via LDC switch '-link-defaultlib-shared'.Aborted (core dumped)
====

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T23:09:23Z

(In reply to Carl Sturtivant from comment #10)
> (In reply to Richard Cattermole from comment #9)

====
$ ldc2 -c main.d
$ ldc2 -of=main -L-E main.o -L-ldl
$ ldc2 -c --relocation-model=pic dynamic_lib.d
$ ldc2 -of=dynamic_lib.so -shared -relocation-model=pic dynamic_lib.o
(dmd-2.107.0)carl@palmtree ~/Documents/dprogs/dl $ main
Aborting from rt/sections_elf_shared.d(605) Only one D shared object allowed for static runtime. Link with shared runtime via LDC switch '-link-defaultlib-shared'.Aborted (core dumped)
====

--- looks like the crash options are the default: not shared for main and shared for the dynamic library.

@dlangBugzillaToGithub
Copy link
Author

alphaglosined commented on 2024-03-01T23:33:42Z

Okay, ldc and dmd have differing implementations of ``rt.sections_elf_shared``.

With ldc yes, you need to stick with only shared library build of druntime, it cannot be mixed.

From what I can tell it's an ordering problem due to not explicitly loading then unloading druntime in the right order.

@dlangBugzillaToGithub
Copy link
Author

sturtivant commented on 2024-03-01T23:56:42Z

(In reply to Richard Cattermole from comment #12)
> From what I can tell it's an ordering problem due to not explicitly loading
> then unloading druntime in the right order.

That's intuitively reasonable.

@thewilsonator thewilsonator added the Druntime Specific to druntime label Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Arch:x86_64 Issues specific to x86_64 Druntime Specific to druntime OS:Linux P1 Severity:major
Projects
None yet
Development

No branches or pull requests

2 participants