Skip to content

LibELF: Implement dlclose similar to how it is done in glibc #24264

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

Closed
wants to merge 9 commits into from

Conversation

DanShaders
Copy link
Contributor

@DanShaders DanShaders commented May 8, 2024

This resolves multiple fixmes in a way original authors intended them to be resolved. I'm still not convinced we need "proper" dlclose but noone seemed to have any strong opinions about it when I asked on Discord.

CC @supercomputer7, you might want to say something about the design of dlclose promise.

PS: Most of the diff is tests, the actual change is about +120 net added loc.

@DanShaders DanShaders requested a review from BertalanD as a code owner May 8, 2024 16:55
@github-actions github-actions bot added the 👀 pr-needs-review PR needs review from a maintainer or community member label May 8, 2024
@@ -45,7 +45,7 @@ namespace {
ByteString s_main_program_path;

// The order of objects here corresponds to the "load order" from POSIX specification.
OrderedHashMap<ByteString, NonnullRefPtr<ELF::DynamicObject>> s_global_objects;
OrderedHashMap<ByteString, NonnullOwnPtr<ELF::DynamicObject>> s_global_objects;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure bout this one. If we need fancy ref-coutning for Dynamic Object, the proper way would be to implement that custom ref-counting on the object directly, rather than inheriting from RefCounted. RefPtr doesn't require you to use RefCounted, simply that the object has the required ref/unref calls.

Copy link
Contributor Author

@DanShaders DanShaders May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it easier to reason about the DynamicObjects' lifetimes when there's a single owner and two separate refcounts that aren't obligatory.

Oh, and there is exactly one place where the objects are created, and exactly one place where they get destroyed.

Copy link
Member

@alimpfard alimpfard May 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into the next commit a bit, I'm not sure what the difference between your proposed whacky ownership model and the "normal" RefPtr model is; dlopen_ref and dlopen_unref are just ref and unref, your manual unref call is exactly equivalent to setting the pointer to null. your manual ref calls can stay as they are.

DanShaders added 8 commits May 8, 2024 13:26
The index will be used to efficiently record unload dependencies of
shared object.
We need a much more convoluted way to count references to DynamicObject
than RefPtr provides to properly support dlclose.
While dlclose is not used often in the wild (and we certainly don't have
references to it in Serenity) and is not required by POSIX to do
anything, I would rather copy glibc's behavior instead of leaving
musl-like no-op behavior. Implementing it properly also motivates a
future in-house __cxa_thread_atexit.
Copy link
Member

@alimpfard alimpfard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TLDR: I'm not convinced any of this is necessary, useful, or even good.

Comment on lines +52 to +53
return position.value();
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please no.

@@ -45,7 +45,7 @@ namespace {
ByteString s_main_program_path;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't understand why we need this.
Most libcs I know of don't go through all this to support something basically no one relies on.

@@ -45,7 +45,7 @@ namespace {
ByteString s_main_program_path;

// The order of objects here corresponds to the "load order" from POSIX specification.
OrderedHashMap<ByteString, NonnullRefPtr<ELF::DynamicObject>> s_global_objects;
OrderedHashMap<ByteString, NonnullOwnPtr<ELF::DynamicObject>> s_global_objects;
Copy link
Member

@alimpfard alimpfard May 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into the next commit a bit, I'm not sure what the difference between your proposed whacky ownership model and the "normal" RefPtr model is; dlopen_ref and dlopen_unref are just ref and unref, your manual unref call is exactly equivalent to setting the pointer to null. your manual ref calls can stay as they are.

@@ -457,6 +457,31 @@ static ErrorOr<void, DlErrorMessage> link_main_library(int flags, DependencyOrde
return {};
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While dlclose is not used often in the wild (and we certainly don't have references to it in Serenity) and is not required by POSIX to do anything, I would rather copy glibc's behavior instead of leaving musl-like no-op behavior.

Why tho?
I'm sorry, but I read that as:

While dlclose doing anything is literally useless, I want to make it do something.

@DanShaders
Copy link
Contributor Author

(Off: and that was me being "excessively" emotional with a single "no, no, no" in the review of 21101 :caret:)

Well, I wrote the code, it hasn't felt like something horrible, I thought "fine, let's pr it, I don't care if it gets accepted or not". I think a single objection is enough though to not merge this.

@DanShaders DanShaders closed this May 9, 2024
@github-actions github-actions bot removed the 👀 pr-needs-review PR needs review from a maintainer or community member label May 9, 2024
@alimpfard
Copy link
Member

I'm not really objecting to it, rather asking you what its purpose is -- is there something you want to do that needs this? some code that does something fun when this behaviour is supported? etc etc.

@DanShaders
Copy link
Contributor Author

I was just convinced that every self-respecting libc should implement dlclose not as a no-op (but that's clearly not the case, see musl). There will indeed be no use for this code currently or in the near future. (And if there ever will be a need, PR is not going anywhere)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants