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

What are the requirements for unloading a library (dlclose)? #526

Open
VorpalBlade opened this issue Aug 13, 2024 · 8 comments
Open

What are the requirements for unloading a library (dlclose)? #526

VorpalBlade opened this issue Aug 13, 2024 · 8 comments

Comments

@VorpalBlade
Copy link

Side question of #525: what about dlclose?

As @RalfJung said, it is a "hornets nest". It is obvious an unsafe operation, but what are the specific safety requirements a user have to uphold to unload a library?

Off the top of my head:

  • That no references to the data or code about to be unloaded still exists, including static data from the library. Lifetimes (in particular 'static) will be a lie here. Is that OK if you ensure you no longer hold any references to it?
  • What about TLS variables and dlclose, this is platform/dynamic linker dependant as I understand it?

Have I missed any concerns? I'm not very familiar with anything except Linux, so there may be platform specific concerns as well.

@RalfJung
Copy link
Member

Lifetimes (in particular 'static) will be a lie here. Is that OK if you ensure you no longer hold any references to it?

Yes that's okay.

What about TLS variables and dlclose, this is platform/dynamic linker dependant as I understand it?

AFAIK it is an unmitigated disaster, which is why macOS just blocks unloading libraries with TLS entirely. On Linux it's not blocked but there is, to my knowledge, no sound way to unload such a library ever, so it might as well be blocked.

@chorman0773
Copy link
Contributor

chorman0773 commented Aug 13, 2024

Note that it's specifically TLS destructors, not TLS variables. Having TLS Variables in a to-be-closed DSO is fine, as long as there aren't any registered destructors. Though, but for pinning, there could be a way to avoid the issue, namely by marking TLS Destructor registrations from a closed DSO as finalized so they don't run at thread exit.

(This might be the solution that I use in LiliumOS)

@CAD97
Copy link

CAD97 commented Aug 13, 2024

It's perhaps worth noting that macOS outright just doesn't unload dylibs in a number of cases that don't support unloading, despite returning a success value when requesting an unload.

TLS dtor behavior is already target dependent at program exit, so it's not particularly surprising that it'd be such for dylib unloading. (Although unmitigated UB is of course worse.)


For dlclose to be sound, I think you'd need to ensure:

  • No references to data owned by the dylib exist outside the dylib.
  • No function pointers to code exported by the dylib exist outside the dylib.
  • No symbols outside the dylib are linked to a symbol exported by the dylib.
  • No running threads are owned by the dylib.

In terms of the opsem modeling dlclose, I think that can straightforwardly be a forced unwind of any terminated threads (i.e. UB, currently) and then popping all borrow tags from all memory owned by the dylib (causing UB if any protectors exist), plus some way to mark the unloaded functions as UB to call.

@chorman0773
Copy link
Contributor

Also:

  • No outstanding TLS Object defined by the dylib have non-trivial destructors

@RalfJung

This comment was marked as resolved.

@VorpalBlade

This comment was marked as resolved.

@chorman0773

This comment was marked as resolved.

@RalfJung

This comment was marked as resolved.

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

No branches or pull requests

4 participants