-
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
build-std compatible sanitizer support #65241
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (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. |
I have OSX but I'm not sure what a suitable test plan or steps would be here? Otherwise I think everything reads pretty reasonably, but I'd want other better people to put their input into the matter :) |
Concrete steps for step 3 suitable for x86_64-unknown-linux-gnu:
|
Is there any documentation for how sanitizers work today? I think that before we make any major changes to the setup, I'd like to see that rectified, so that the new design can be described as an update to the documentation. The rustc-guide would be a suitable place for such a thing. We could also hold a design meeting, but I don't think that's necessarily required, since sanitizers are still experimental. |
Honestly, because they are a -Z flag, and thus nightly only, I think that documentation has not emerged because people don't know they exist, can't access them when they need stable, or have developed other work arounds. For example, I'm required to setup RUSTC_BOOTSTRAP=1 in my makefiles to use stable compilers + -Z with sanitizers and FFI. I also think that because their major value is with FFI, and that requires the C components to always work with sanitizers, there are not many projects currently using them broadly. So this all led to the sanitizers being a super niche feature, wildly useful for people like me who has a C code base that is sanitized and able to develop the tricks to use them with Rust FFI, but most people don't have that set of overlapping scenarios to bring this into peoples minds. I think that if the first line of the documentation was "you need nightly to use sanitizers" that's already a major barrier to getting this used more broadly. So I think we need to seriously discuss how we get features like this out from behind nightly only. |
☔ The latest upstream changes (presumably #65388) made this pull request unmergeable. Please resolve the merge conflicts. |
@nikomatsakis japaric published user oriented documentation at https://github.com/japaric/rust-san. Substantial part of it is dedicated to answering the question how to rebuild I don't think there was any documentation for implementation in rustc, apart Related documentation changes in rustc-guide rust-lang/rustc-dev-guide#466. |
☔ The latest upstream changes (presumably #65422) made this pull request unmergeable. Please resolve the merge conflicts. |
Thanks for working on this. After some discussions in Discord it seems that this PR is the right way to move forward. As you have noticed, my fix for #64629 was not comprehensive. I am still facing issues where sanitizer runtimes are linked to libraries and we still cannot build Firefox with TSan for that reason. |
@tmiasko first off, thanks a ton for the rustc-guide PR! As I wrote in my review, I suspect that the 'how to use sanitizer' material would be better off in the src/doc/rustc directory, as part of the "rustc book". Do you think you could leave a few notes in the rustc-guide describing how sanitizer integration works? (like, it seems like we have to link some LLVM libraries somewhere, and we are copying some files around, why are we doing that?) My motivation here is that, particularly for these "little used, perenially unstable" features, I'd like to have some notes on how things work so that if we have to fix bugs we have some idea where to start. (Although this sparks an idea for me that maybe, for features like these, we should also have people kind of "sign up" as maintainers that can be pinged if problems arise... right now, we don't have any notion of who those people might be. I presume you'd be up for that?) To be clear: if there were some docs on how |
I just wanted to note that adding unstable documentation to the rustc book is a little unusual, as it doesn't contain any unstable docs right now. Normally the unstable documentation goes in the Unstable Book. I personally don't care too much in this case, but thought I would point it out. EDIT: It may want to at least mention that the chapter is about an unstable feature. |
@ehuss thanks for suggestion, the unstable-book seems more appropriate. The I moved the user oriented parts to unstable-book (new commit here). The @nikomatsakis sure, you cc me on issues related to sanitizers. |
Hmm, I'm ok with the unstable book too. I tend to think that means nobody will ever find it there, but maybe that's the point. |
To elaborate on my previous comment, by "maybe that's the point" I meant:
That said, maybe it'd be useful to extend the rustc book with a pointer to the unstable guide to say something like "you can find documentation on unstable options here". I do appreciate the idea of making it extra clear when things are unstable. The same could apply to the self-profile options. |
📌 Commit dd4d6a9 has been approved by |
build-std compatible sanitizer support ### Motivation When using `-Z sanitizer=*` feature it is essential that both user code and standard library is instrumented. Otherwise the utility of sanitizer will be limited, or its use will be impractical like in the case of memory sanitizer. The recently introduced cargo feature build-std makes it possible to rebuild standard library with arbitrary rustc flags. Unfortunately, those changes alone do not make it easy to rebuild standard library with sanitizers, since runtimes are dependencies of std that have to be build in specific environment, generally not available outside rustbuild process. Additionally rebuilding them requires presence of llvm-config and compiler-rt sources. The goal of changes proposed here is to make it possible to avoid rebuilding sanitizer runtimes when rebuilding the std, thus making it possible to instrument standard library for use with sanitizer with simple, although verbose command: ``` env CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=-Zsanitizer=thread cargo test -Zbuild-std --target x86_64-unknown-linux-gnu ``` ### Implementation * Sanitizer runtimes are no long packed into crates. Instead, libraries build from compiler-rt are used as is, after renaming them into `librusc_rt.*`. * rustc obtains runtimes from target libdir for default sysroot, so that they are not required in custom build sysroots created with build-std. * The runtimes are only linked-in into executables to address issue rust-lang#64629. (in previous design it was hard to avoid linking runtimes into static libraries produced by rustc as demonstrated by sanitizer-staticlib-link test, which still passes despite changes made in rust-lang#64780). * When custom llvm-config is specified during build process, the sanitizer runtimes will be obtained from there instead of begin rebuilding from sources in src/llvm-project/compiler-rt. This should be preferable since runtimes used should match instrumentation passes. For example there have been nine version of address sanitizer ABI. Note this marked as a draft PR, because it is currently untested on OS X (I would appreciate any help there). cc @kennytm, @japaric, @Firstyear, @choller
build-std compatible sanitizer support ### Motivation When using `-Z sanitizer=*` feature it is essential that both user code and standard library is instrumented. Otherwise the utility of sanitizer will be limited, or its use will be impractical like in the case of memory sanitizer. The recently introduced cargo feature build-std makes it possible to rebuild standard library with arbitrary rustc flags. Unfortunately, those changes alone do not make it easy to rebuild standard library with sanitizers, since runtimes are dependencies of std that have to be build in specific environment, generally not available outside rustbuild process. Additionally rebuilding them requires presence of llvm-config and compiler-rt sources. The goal of changes proposed here is to make it possible to avoid rebuilding sanitizer runtimes when rebuilding the std, thus making it possible to instrument standard library for use with sanitizer with simple, although verbose command: ``` env CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=-Zsanitizer=thread cargo test -Zbuild-std --target x86_64-unknown-linux-gnu ``` ### Implementation * Sanitizer runtimes are no long packed into crates. Instead, libraries build from compiler-rt are used as is, after renaming them into `librusc_rt.*`. * rustc obtains runtimes from target libdir for default sysroot, so that they are not required in custom build sysroots created with build-std. * The runtimes are only linked-in into executables to address issue rust-lang#64629. (in previous design it was hard to avoid linking runtimes into static libraries produced by rustc as demonstrated by sanitizer-staticlib-link test, which still passes despite changes made in rust-lang#64780). * When custom llvm-config is specified during build process, the sanitizer runtimes will be obtained from there instead of begin rebuilding from sources in src/llvm-project/compiler-rt. This should be preferable since runtimes used should match instrumentation passes. For example there have been nine version of address sanitizer ABI. Note this marked as a draft PR, because it is currently untested on OS X (I would appreciate any help there). cc @kennytm, @japaric, @Firstyear, @choller
Rebased without commit that attempted to reenable leak sanitizer testcase. |
@bors: r+ |
📌 Commit e88f071 has been approved by |
⌛ Testing commit e88f071 with merge 41925383b20cd7361be8ef3e8b7a22b61f272611... |
💔 Test failed - checks-azure |
@bors p=0 |
@bors retry
|
build-std compatible sanitizer support ### Motivation When using `-Z sanitizer=*` feature it is essential that both user code and standard library is instrumented. Otherwise the utility of sanitizer will be limited, or its use will be impractical like in the case of memory sanitizer. The recently introduced cargo feature build-std makes it possible to rebuild standard library with arbitrary rustc flags. Unfortunately, those changes alone do not make it easy to rebuild standard library with sanitizers, since runtimes are dependencies of std that have to be build in specific environment, generally not available outside rustbuild process. Additionally rebuilding them requires presence of llvm-config and compiler-rt sources. The goal of changes proposed here is to make it possible to avoid rebuilding sanitizer runtimes when rebuilding the std, thus making it possible to instrument standard library for use with sanitizer with simple, although verbose command: ``` env CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=-Zsanitizer=thread cargo test -Zbuild-std --target x86_64-unknown-linux-gnu ``` ### Implementation * Sanitizer runtimes are no long packed into crates. Instead, libraries build from compiler-rt are used as is, after renaming them into `librusc_rt.*`. * rustc obtains runtimes from target libdir for default sysroot, so that they are not required in custom build sysroots created with build-std. * The runtimes are only linked-in into executables to address issue #64629. (in previous design it was hard to avoid linking runtimes into static libraries produced by rustc as demonstrated by sanitizer-staticlib-link test, which still passes despite changes made in #64780). cc @kennytm, @japaric, @Firstyear, @choller
☀️ Test successful - checks-azure |
Motivation
When using
-Z sanitizer=*
feature it is essential that both user code andstandard library is instrumented. Otherwise the utility of sanitizer will be
limited, or its use will be impractical like in the case of memory sanitizer.
The recently introduced cargo feature build-std makes it possible to rebuild
standard library with arbitrary rustc flags. Unfortunately, those changes alone
do not make it easy to rebuild standard library with sanitizers, since runtimes
are dependencies of std that have to be build in specific environment,
generally not available outside rustbuild process. Additionally rebuilding them
requires presence of llvm-config and compiler-rt sources.
The goal of changes proposed here is to make it possible to avoid rebuilding
sanitizer runtimes when rebuilding the std, thus making it possible to
instrument standard library for use with sanitizer with simple, although
verbose command:
Implementation
from compiler-rt are used as is, after renaming them into
librusc_rt.*
.they are not required in custom build sysroots created with build-std.
(in previous design it was hard to avoid linking runtimes into static
libraries produced by rustc as demonstrated by sanitizer-staticlib-link
test, which still passes despite changes made in Only add sanitizer runtimes when linking an executable (#64629). #64780).
cc @kennytm, @japaric, @Firstyear, @choller