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

Updated library isn't always correctly reloaded #1

Open
t-mw opened this issue Feb 2, 2018 · 8 comments
Open

Updated library isn't always correctly reloaded #1

t-mw opened this issue Feb 2, 2018 · 8 comments

Comments

@t-mw
Copy link

t-mw commented Feb 2, 2018

Thanks for sharing this library.

I'm not sure if this is a bug in live-reloading-rs, rust_libloading or OS X, but after triggering a live reload in macOS High Sierra (10.13.3) the old version of the library continues to be used.

For example, after updating the demo application to use increments of 5 instead of 2 and recompiling with cargo build --lib, the console output looks like this:

Counter: 42.
Counter: 44.
Unloaded at 44.
Reloaded at 44.
Counter: 46.
Counter: 48.

The same process on OS X El Capitan (10.11.6) produces the correct output.

Just putting this out there in case other people have the same issue.

@porglezomp
Copy link
Contributor

Hi @t-mw, thanks for the issue. I ran into this doing game development a few months ago and eventually concluded that this regressed for me going from Rust 1.19.0 to 1.20.0, but that the new behavior is the best that can guaranteed by POSIX, so we were just getting lucky earlier. As a first workaround, perhaps see if an older version of Rust behaves like you want?

If you want to properly fix it, see the Rust issue rust-lang/rust#44365 for some discussion of their workaround. If you want to contribute, trying to adapt the suggested build.rs workaround into a library function that people could stick in their own build.rs would be a great help. If you don't want to do it, I might find time myself sometime soon.

@porglezomp porglezomp changed the title Updated library isn't reloaded on macOS High Sierra (10.13.3) Updated library isn't always correctly reloaded Feb 2, 2018
@porglezomp
Copy link
Contributor

I believe there might also be some file-locking issues with libraries on Windows that I'm not dealing with, so the fix that builds to a random/hashed/counter library name would also be a great solution to deal with that.

@t-mw
Copy link
Author

t-mw commented Feb 2, 2018

Hi, thanks for the links - I'll have a read through the discussion. Confusingly, I'm able to get tiny-live-code-example working with a commit pre-dating the workaround (Ryan1729/tiny-live-code-example@c9b6472) and using Rust 1.23.0 on macOS High Sierra. live-reloading-rs doesn't work for me with Rust 1.23.0 or 1.19.0 on macOS High Sierra, but does work for me with Rust 1.23.0 on a different computer running OS X El Capitan, so there might be more than one issue at play here.

t-mw added a commit to t-mw/live-reloading-rs that referenced this issue Feb 2, 2018
@t-mw
Copy link
Author

t-mw commented Feb 2, 2018

It looks like updating the library name fixes the issue for me. To automate it, I thought that ideally the build script would generate the library name, but it seems that --cargo-name can't be modified from inside build.rs.

In the end I went with t-mw@4f7be34, which is very hacky in that it relies on modifying the cargo manifest, but otherwise it should be set and forget. Without the build script the library should revert to the old behavior of using a fixed name.

@porglezomp porglezomp added the bug label Feb 3, 2018
@t-mw
Copy link
Author

t-mw commented Feb 3, 2018

The build script has the disadvantage that it creates a new version of the library for each change, which for whatever reason is slower than compiling to the same target. This shell script works with the changes in the commit above on OS X, but doesn't need the build script changes and avoids compiling to new targets.

@porglezomp
Copy link
Contributor

If I understand correctly, that will copy the library to another path after compiling, then fix it up so it gets loaded. Is install_name_tool in there changing the path embedded in the library so the loader recognizes it as a different library? If so, do you think we could handle that by spawning the rename/fixup process before reload in live-reloading?

Do you know what an alternative to install_name_tool might be on Linux/Windows (Googling I found maybe PatchELF on Linux?)

@t-mw
Copy link
Author

t-mw commented Feb 4, 2018

That's right - there's a path embedded in the dylib as LC_ID_DYLIB (can be seen with otool -l libreloadable.dylib) that references a copy of the library in target/debug/deps. Updating that path with install_name_tool fixes the issue for me, where just renaming the file doesn't. Then the changes to src/lib.rs in t-mw@4f7be34 cause live-reloading to pick up the latest version of the library of the format libreloadable_$timestamp.dylib when the watcher for the build directory triggers.

The equivalent on Linux might be patchelf --set-soname, but for Windows I'm not sure what it would be. I'm also not sure what side-effects changing the path like that could have on the various platforms (e.g. breaking debug symbols) and it's not very robust to changes in the build output format / directory structure, but otherwise there's no reason it couldn't be done within live-reloading.

@t-mw
Copy link
Author

t-mw commented Jan 8, 2020

I tried out Linux (specifically Arch), and there it's enough to just copy the library with a new filename without patching it. So this script in combination with t-mw@4f7be34 works. Looks like mac still needs the patching though even with the latest Rust.

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

No branches or pull requests

2 participants