Repository navigation
MemorySanitizer detects an use of unitialized value in the test runner (rustc --test) #39610
Copy link
Copy link
Closed
Labels
A-libtestArea: `#[test]` / the `test` libraryArea: `#[test]` / the `test` libraryA-sanitizersArea: Sanitizers for correctness and code qualityArea: Sanitizers for correctness and code qualityC-bugCategory: This is a bug.Category: This is a bug.
Description
STR
$ cargo new --lib test-runner && cd $_
$ edit src/lib.rs && cat $_
#[test]
fn foo() {}$ RUSTFLAGS="-Z sanitizer=memory" cargo test --target x86_64-unknown-linux-gnu
Running target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235
Uninitialized bytes in __interceptor_memchr at offset 13 inside [0x70400000ef60, 23)
==6915==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x55aec536a8b5 in std::ffi::c_str::CString::_new::h1600b539eb5d8b8c ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xc58b5)
#1 0x55aec537399a in std::sys::imp::fs::stat::h72120555244bec39 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xce99a)
#2 0x55aec5355b18 in std::fs::metadata::h4ae9b0fd118f3836 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xb0b18)
#3 0x55aec535bea8 in term::terminfo::searcher::get_dbpath_for_term::hc53288f466988180 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xb6ea8)
#4 0x55aec535b3f1 in term::terminfo::TermInfo::from_name::hb95f189f4c99eccf ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xb63f1)
#5 0x55aec535b1a2 in term::terminfo::TermInfo::from_env::h45b8e5476a2a09d7 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xb61a2)
#6 0x55aec5365c70 in term::stdout::h84d7912730b73cf4 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xc0c70)
#7 0x55aec52d28bd in _$LT$test..ConsoleTestState$LT$T$GT$$GT$::new::h937954646ef1f1d9 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x2d8bd)
#8 0x55aec52d481a in test::run_tests_console::h7b41f829f623d5c0 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x2f81a)
#9 0x55aec52cfdb8 in test::test_main::hae140f91361b0544 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x2adb8)
#10 0x55aec52d06ce in test::test_main_static::h9b2aae5d6f64eac6 ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x2b6ce)
#11 0x55aec52be9a3 in test_runner::__test::main::h164d7dfa966cbb3f $PWD/src/lib.rs:1
#12 0x55aec537d5d6 in __rust_maybe_catch_panic ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xd85d6)
#13 0x55aec5376bc9 in std::rt::lang_start::h6954771f55df116b ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xd1bc9)
#14 0x55aec52bea19 in main ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x19a19)
#15 0x7fc24cf2f290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
#16 0x55aec52be839 in _start ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0x19839)
SUMMARY: MemorySanitizer: use-of-uninitialized-value ($PWD/target/x86_64-unknown-linux-gnu/debug/deps/test_runner-d861d6557762b235+0xc58b5) in std::ffi::c_str::CString::_new::h1600b539eb5d8b8c
Exiting
error: test failed
Meta
TODO Sanitizers are not yet in tree. (cf. #38699)
Reacted by Corey Farwell, Tyler Neely, Maxime Guerreiro and Felipe S. S. Schneider
Reacted by LR.X
Metadata
Metadata
Assignees
Labels
A-libtestArea: `#[test]` / the `test` libraryArea: `#[test]` / the `test` libraryA-sanitizersArea: Sanitizers for correctness and code qualityArea: Sanitizers for correctness and code qualityC-bugCategory: This is a bug.Category: This is a bug.
Activity
alexcrichton commentedon Feb 7, 2017
Naively I'd say this is a false positive, but I could be wrong! This stack trace looks familiar, though, as I think I've seen it in terms of valgrind warnings in the past as well. (although I think those may have been false positives as well)
dimbleby commentedon Feb 17, 2017
Apparently:
I'm guessing that we're just using the regular libc?
Also, here is much the same thing happening in another project.
alexcrichton commentedon Feb 17, 2017
Thanks for the info @dimbleby! Right now I believe the standard library is not compiled with
-fsanitize=memory, which could be (and likely is) the cause of these problems.@japaric WDYT about modifying
-Cltoto work here? There's already custom passes with-C lto + -C panic=abortand I think we could easily modify LTO to apply the necessary LLVM attribute everywhere as well.After that I think we could generate a nicer error up front saying "not everything is compiled with the memory sanitizer" than perhaps deferring this to runtime.
dimbleby commentedon Feb 18, 2017
Not sure whether we're at cross purposes, but just to make sure: I wasn't talking about the Rust standard library but the regular C libc - which is, I suppose, where the
memchr()in the stack is ultimately coming from.Having said that, it sounds as though both would need to be instrumented for the memory sanitizer to give reliable results...
japaric commentedon Feb 18, 2017
I think this is the root of the problem because if you run the sanitizer using Xargo, to force intrumentation of the whole std facade, then there's no error.
@dimbleby I don't think one needs to compile libc with -fsanitize=memory as the sanitizer runtime that we link already instruments most of libc functions (memcpy, memchr, etc.) by overriding those symbols. The example you linked doesn't recompile libc either. We should, though, compile other C libraries that get linked to the final executable with -fsanitize=memory. I think that could be handled with a
CARGO_SANITIZER=memoryenv variable that build scripts can read to decide whether to compile code with-fsanitizeor not.@alexcrichton
We can't ship a
stdfacade compiled with-Z sanitizerbecause if a single function is compiled with-Z sanitizerthen you have to link the sanitizer runtime or your executable won't link due to missing symbols.Interesting. I didn't know about that. I'll take a look. Do you know if that also forces the recompilation of functions that are already contained in e.g.
libstd.rlibin the form of object files?Do you mean making it so that a crate won't compile with
-Z sanitizerif-C ltois not used?alexcrichton commentedon Feb 21, 2017
Excellent point! Although unless we could ship two libstd builds and select between them dynamically 😉
(yeah let's not do that)
Yeah the "recompilation" here is that we build a massive wad of LLVM IR representing the entire world of Rust, we then optimize it all again, and then emit object code again. That re-codegens the entire world, but doesn't "recompile" the entire world (depending on your definition)
Yeah that's what I'm thinking. Unless all libraries are compiled with the right sanitizer then this is basically guaranteed to return false positives and errors, right?
danburkert commentedon Jul 2, 2017
Is there a way to pass
-fsanitize-blacklistto work around this until a proper fix lands?gnzlbg commentedon Feb 2, 2018
What we could do is add targets for sanitized builds. I want to just
cargo test --target x86_64-unknown-linux-gnu-msanand have all my dependencies compiled with-fsanitize=memory(and origins and what not) and linked against an appropriately compiledstdlibrary.rustupshould be able to ship this target.gnzlbg commentedon Feb 28, 2018
@alexcrichton how hard would it be to add a new target:
x86_64-unknown-linux-gnu-msanthat ships its own std-lib compiled with-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g?The memory sanitizer is Linux-only, and probably
x86_64only as well, so this is really all that we would need (maybe ax86_64-unknown-linux-musl-msanif there is desire for this in the future).alexcrichton commentedon Feb 28, 2018
It unfortunately wouldn't be the easiest thing but it also woudln't necessarily be too hard. It's definitely pretty hard to "do on a whim", so we'd want to commit to the design before doing so.
steveklabnik commentedon Oct 27, 2019
Triage: not aware of any changes here.
Run Sanitizers and Valgrind on tests as part of CI
Run Sanitizers and Valgrind on tests as part of CI
tmiasko commentedon Jan 12, 2020
steveklabnik commentedon Mar 15, 2020
Okay, looks like we're passing then! Giving this a close unless anyone else can reproduce.
vertexclique commentedon Mar 25, 2020
This is just reproduced in my current build with
libc v0.2.67:tesuji commentedon Mar 25, 2020
Did you try with build-std?