prevent unloading of all GNU/Linux objects by setting DF_1_NODELETE - #158402
prevent unloading of all GNU/Linux objects by setting DF_1_NODELETE#158402joboet wants to merge 1 commit into
DF_1_NODELETE#158402Conversation
|
These commits modify compiler targets. |
|
r? @mejrs rustbot has assigned @mejrs. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
bc193bb to
842b8c5
Compare
|
The job Click to see the possible cause of the failure (guessed by this bot) |
|
This would break hot code reloading, wouldn't it? While hot code reloading isn't sound, there are use cases where it is the only approach to get reasonable iteration times as the program takes some time to load and more importantly has a lot of non-serialized state like for example the entire world in the case of a game. |
|
Not really, it just takes more memory – |
|
AFAIK dlopen will reuse an existing loaded library if the path matches. Also a memory leak can easily cause memory exhaustion if you hot reload many times without restarting the program. And on Windows it will prevent cargo from replacing the DLL entirely as opened files can't be deleted on Windows by default. (I know this PR doesn't apply to Windows, but if you do it for glibc, why wouldn't you do it for Windows too?)
That only works for read-only pages, not writable pages (including those that are read-only at runtime but contain relocations that are applied at load time like those in In any case dlclose itself has the safety obligation of checking that the dylib supports unloading. It is not the responsibility of the dylib to prevent unloading if it isn't safe to unload. |
|
r? bjorn3 |
|
I think it would be unfortunate to break the ability to write a library that can be unloaded; that may be needed for parity with an existing C library for example. Is there a concrete list of things that are making the assumption this doesn't happen to which we could perhaps attach this? For example, maybe if you use a thread_local! with a significant Drop then we apply this restriction?
What parts of the Rust abstract machine are still running after a dlclose? |
|
Thread locals already prevent glibc from unloading a dylib. It is more background threads, atexit handlers or references to data inside the dylib. |
glibc supports unloading dynamic libraries through dlclose. However, unloading dynamic libraries is fundamentally incompatible with assumptions made by
stdand much of the Rust ecosystem. Notably, the'staticlifetime is commonly expected to last until the termination of the abstract machine, which is required for the soundness of e.g. thread-local destructors. Hence, this PR disables unloading for all GNU/Linux Rust objects by having the linker set the DF_1_NODELETE flag (LD docs/LLD docs). Note that this flag does not makedlclosefail, it will just not have any effect.I suppose this requires a MCP? Not sure how this is handled...