-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Only link res_init() on GNU/*nix #47334
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
This seems like a perfectly reasonable fix to me. |
Thanks for the PR! Could this perhaps be refactored a little differently though to avoid |
@alexcrichton the code that's there currently already uses If we do factor out the refresh into its own file, I propose adding fn on_resolver_failure(e: io::Error) -> io::Error { e } to each of the use sys::net::on_resolver_failure;
// ...
match ... {
Ok(..) => ...,
Err(e) => ::sys::net::on_resolver_failure(e),
} |
Yeah I just find it's personally best to cut down on this sort of cfg traffic is possible, and what you've suggested should do the trick! |
From what I can see that would only remove the |
@etaoins yes, I think the concern is specifically with |
Ah yeah this'd just be moving the cfg, we'd still have it for sure in the unix/net.rs file |
@jonhoo @alexcrichton Updated with |
if ret != 0 { | ||
return Err(io::Error::last_os_error()); | ||
} | ||
unsafe { libc::res_init() }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any particular reason why you chose to prefer the original resolver error over any potential res_init
error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered this but:
-
That's what the code in
master
is doing. The error fromres_init_if_glibc_before_2_26
is discarded and the original error fromgetaddrinfo()
is returned. -
Callers are probably expecting
getaddrinfo()
-type errors fromlookup_host()
(e.g.EAI_FAIL
) . This is especially true since this will only be happening on an increasingly small fraction of platforms in obscure cases so it won't get much testing. I think returning theres_init()
result here would be surprising. -
res_init()
does not return a well defined set of error codes. It's not clear that's it's settingerrno
at all from reading the glibc manage -
I'm not convinced that
res_init()
will always be the most proximate error. It's possible thatres_init()
is returning a useful report on why the resolution system isn't working (but I have my doubts due to point 3). However, it's also possible that thegetaddrinfo()
is returning more useful information and theres_init()
is failing for some inconsequential reason.
I kept the error code return from on_resolver_failure
in case some platform wants to modify the error on return but it's just directly returned at the moment.
If there's a strong opinion in the other direction I can change the error behaviour but I want to reiterate that would be a functional change from master
.
📌 Commit 6289732 has been approved by |
@bors r- Compilation failed on Windows.
You need to define |
I don't think distinguishing on Windows should be needed. @etaoins make sure you define the |
@kennytm @jonhoo Unrelated to Windows but it seems unfortunate that every platform needs to define |
@bors: r+ |
📌 Commit de391b8 has been approved by |
@bors r=alexcrichton There's no simple way to trigger a full rebuild without merging, but since this has broken rollup twice I'd no longer consider this when creating a rollup 😃 |
📌 Commit 5b6aa8b has been approved by |
Hmm.. I don't think 5b6aa8bac94a12329ef78e7c1636a4c197fbb0db will work. For the |
To workaround a bug in glibc <= 2.26 lookup_host() calls res_init() based on the glibc version detected at runtime. While this avoids calling res_init() on platforms where it's not required we will still end up linking against the symbol. This causes an issue on macOS where res_init() is implemented in a separate library (libresolv.9.dylib) from the main libc. While this is harmless for standalone programs it becomes a problem if Rust code is statically linked against another program. If the linked program doesn't already specify -lresolv it will cause the link to fail. This is captured in issue #46797 Fix this by hooking in to the glibc workaround in `cvt_gai` and only activating it for the "gnu" environment on Unix This should include all glibc platforms while excluding musl, windows-gnu, macOS, FreeBSD, etc. This has the side benefit of removing the #[cfg] in sys_common; only unix.rs has code related to the workaround now.
@jonhoo @alexcrichton
Let me know what you think |
@bors: r+ Looks good to me! |
📌 Commit 090a968 has been approved by |
…nix, r=alexcrichton Only link res_init() on GNU/*nix To workaround a bug in glibc <= 2.26 lookup_host() calls res_init() based on the glibc version detected at runtime. While this avoids calling res_init() on platforms where it's not required we will still end up linking against the symbol. This causes an issue on macOS where res_init() is implemented in a separate library (libresolv.9.dylib) from the main libc. While this is harmless for standalone programs it becomes a problem if Rust code is statically linked against another program. If the linked program doesn't already specify -lresolv it will cause the link to fail. This is captured in issue rust-lang#46797 Fix this by hooking in to the glibc workaround in `cvt_gai` and only activating it for the "gnu" environment on Unix This should include all glibc platforms while excluding musl, windows-gnu, macOS, FreeBSD, etc. This has the side benefit of removing the #[cfg] in sys_common; only unix.rs has code related to the workaround now. Before this commit: ```shell > cat main.rs use std::net::ToSocketAddrs; #[no_mangle] pub extern "C" fn resolve_test() -> () { let addr_list = ("google.com.au", 0).to_socket_addrs().unwrap(); println!("{:?}", addr_list); } > rustc --crate-type=staticlib main.rs > clang libmain.a test.c -o combined Undefined symbols for architecture x86_64: "_res_9_init", referenced from: std::net::lookup_host::h93c17fe9ad38464a in libmain.a(std-826c8d3b356e180c.std0.rcgu.o) ld: symbol(s) not found for architecture x86_64 clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation) ``` Afterwards: ```shell > rustc --crate-type=staticlib main.rs > clang libmain.a test.c -o combined > ./combined IntoIter([V4(172.217.25.131:0)]) ``` Fixes rust-lang#46797
…nix, r=alexcrichton Only link res_init() on GNU/*nix To workaround a bug in glibc <= 2.26 lookup_host() calls res_init() based on the glibc version detected at runtime. While this avoids calling res_init() on platforms where it's not required we will still end up linking against the symbol. This causes an issue on macOS where res_init() is implemented in a separate library (libresolv.9.dylib) from the main libc. While this is harmless for standalone programs it becomes a problem if Rust code is statically linked against another program. If the linked program doesn't already specify -lresolv it will cause the link to fail. This is captured in issue rust-lang#46797 Fix this by hooking in to the glibc workaround in `cvt_gai` and only activating it for the "gnu" environment on Unix This should include all glibc platforms while excluding musl, windows-gnu, macOS, FreeBSD, etc. This has the side benefit of removing the #[cfg] in sys_common; only unix.rs has code related to the workaround now. Before this commit: ```shell > cat main.rs use std::net::ToSocketAddrs; #[no_mangle] pub extern "C" fn resolve_test() -> () { let addr_list = ("google.com.au", 0).to_socket_addrs().unwrap(); println!("{:?}", addr_list); } > rustc --crate-type=staticlib main.rs > clang libmain.a test.c -o combined Undefined symbols for architecture x86_64: "_res_9_init", referenced from: std::net::lookup_host::h93c17fe9ad38464a in libmain.a(std-826c8d3b356e180c.std0.rcgu.o) ld: symbol(s) not found for architecture x86_64 clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation) ``` Afterwards: ```shell > rustc --crate-type=staticlib main.rs > clang libmain.a test.c -o combined > ./combined IntoIter([V4(172.217.25.131:0)]) ``` Fixes rust-lang#46797
@etaoins 🎉 |
I'm late to the party, but I'm curious whether anyone tried using |
This typo was introduced in rust-lang#47334. A couple tests bitrotted as a result, so we fix those too, and move them to a more sensible place.
fix a typo: taget_env -> target_env This typo was introduced in rust-lang#47334. A couple tests bitrotted as a result, so we fix those too, and move them to a more sensible place. Is there some lint we could turn on that would've caught this? It's a drag that cfg typos can silently pass through the compiler.
fix a typo: taget_env -> target_env This typo was introduced in rust-lang#47334. A couple tests bitrotted as a result, so we fix those too, and move them to a more sensible place. Is there some lint we could turn on that would've caught this? It's a drag that cfg typos can silently pass through the compiler.
fix a typo: taget_env -> target_env This typo was introduced in rust-lang#47334. A couple tests bitrotted as a result, so we fix those too, and move them to a more sensible place. Is there some lint we could turn on that would've caught this? It's a drag that cfg typos can silently pass through the compiler.
fix a typo: taget_env -> target_env This typo was introduced in rust-lang#47334. A couple tests bitrotted as a result, so we fix those too, and move them to a more sensible place. Is there some lint we could turn on that would've caught this? It's a drag that cfg typos can silently pass through the compiler.
fix a typo: taget_env -> target_env This typo was introduced in rust-lang#47334. A couple tests bitrotted as a result, so we fix those too, and move them to a more sensible place. Is there some lint we could turn on that would've caught this? It's a drag that cfg typos can silently pass through the compiler.
To workaround a bug in glibc <= 2.26 lookup_host() calls res_init() based on the glibc version detected at runtime. While this avoids calling res_init() on platforms where it's not required we will still end up linking against the symbol.
This causes an issue on macOS where res_init() is implemented in a separate library (libresolv.9.dylib) from the main libc. While this is harmless for standalone programs it becomes a problem if Rust code is statically linked against another program. If the linked program doesn't already specify -lresolv it will cause the link to fail. This is captured in issue #46797
Fix this by hooking in to the glibc workaround in
cvt_gai
and only activating it for the "gnu" environment on Unix This should include all glibc platforms while excluding musl, windows-gnu, macOS, FreeBSD, etc.This has the side benefit of removing the #[cfg] in sys_common; only unix.rs has code related to the workaround now.
Before this commit:
Afterwards:
Fixes #46797