Rust: Compiling with -Z sanitizer=address aborts

Created on 11 Oct 2017  路  14Comments  路  Source: rust-lang/rust

Steps:

git clone https://github.com/burntsushi/byteorder
cd byteorder
RUSTFLAGS="-Z sanitizer=address" cargo build

Error:

rustc: /checkout/src/llvm/include/llvm/ADT/StringRef.h:236: char llvm::StringRef::operator[](size_t) const: Assertion `Index < Length && "Invalid index!"' failed.
error: Could not compile `byteorder`.

Stack trace from GDB:

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffe5bff700 (LWP 74841)]
0x00007ffff7379c37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7379c37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff737d028 in __GI_abort () at abort.c:89
#2  0x00007ffff7372bf6 in __assert_fail_base (fmt=0x7ffff74c7018 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x7ffff019e7d8 "Index < Length && \"Invalid index!\"", file=file@entry=0x7ffff02f7b60 "/checkout/src/llvm/include/llvm/ADT/StringRef.h", line=line@entry=236,
    function=function@entry=0x7ffff1343260 <_ZZNK4llvm9StringRefixEmE19__PRETTY_FUNCTION__> "char llvm::StringRef::operator[](size_t) const") at assert.c:92
#3  0x00007ffff7372ca2 in __GI___assert_fail (assertion=0x7ffff019e7d8 "Index < Length && \"Invalid index!\"", file=0x7ffff02f7b60 "/checkout/src/llvm/include/llvm/ADT/StringRef.h", line=236, function=0x7ffff1343260 <_ZZNK4llvm9StringRefixEmE19__PRETTY_FUNCTION__> "char llvm::StringRef::operator[](size_t) const") at assert.c:101
#4  0x00007fffefef4661 in llvm::GlobalValue::getGlobalIdentifier(llvm::StringRef, llvm::GlobalValue::LinkageTypes, llvm::StringRef) () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/../lib/librustc_llvm-fcc579f01f90936f.so
#5  0x00007fffefef46f1 in llvm::GlobalValue::getGlobalIdentifier() const () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/../lib/librustc_llvm-fcc579f01f90936f.so
#6  0x00007fffeee10d9d in llvm::GlobalValue::getGUID() const () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/../lib/librustc_llvm-fcc579f01f90936f.so
#7  0x00007fffefd291b6 in llvm::buildModuleSummaryIndex(llvm::Module const&, std::function<llvm::BlockFrequencyInfo* (llvm::Function const&)>, llvm::ProfileSummaryInfo*)::{lambda(llvm::ValueInfo const&)#2}::operator()(llvm::ValueInfo const&) const () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/../lib/librustc_llvm-fcc579f01f90936f.so
#8  0x00007fffefd2c25f in llvm::buildModuleSummaryIndex(llvm::Module const&, std::function<llvm::BlockFrequencyInfo* (llvm::Function const&)>, llvm::ProfileSummaryInfo*) () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/../lib/librustc_llvm-fcc579f01f90936f.so
#9  0x00007fffefd2c8de in llvm::ModuleSummaryIndexWrapperPass::runOnModule(llvm::Module&) () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/../lib/librustc_llvm-fcc579f01f90936f.so
#10 0x00007fffeff2a60f in llvm::legacy::PassManagerImpl::run(llvm::Module&) () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/../lib/librustc_llvm-fcc579f01f90936f.so
#11 0x00007fffee79e7d4 in LLVMRustWriteThinBitcodeToFile () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/../lib/librustc_llvm-fcc579f01f90936f.so
#12 0x00007ffff58d0363 in rustc_trans::back::write::codegen::h48e75414b21460bd () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/librustc_trans-f1fc6dd8a33f17ba.so
#13 0x00007ffff58656e5 in std::sys_common::backtrace::__rust_begin_short_backtrace::ha443b2c90c1dbbde () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/librustc_trans-f1fc6dd8a33f17ba.so
#14 0x00007ffff58679b8 in std::panicking::try::do_call::h768fcd8aa8451e7a () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/librustc_trans-f1fc6dd8a33f17ba.so
#15 0x00007ffff77c3bdd in panic_unwind::__rust_maybe_catch_panic () at /checkout/src/libpanic_unwind/lib.rs:99
#16 0x00007ffff588af63 in _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::hab9046e04a0431df () from /usr/local/google/home/dgreid/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/../lib/../lib/librustc_trans-f1fc6dd8a33f17ba.so
#17 0x00007ffff778820c in call_once<(),()> () at /checkout/src/liballoc/boxed.rs:736
#18 start_thread () at /checkout/src/libstd/sys_common/thread.rs:24
#19 std::sys::imp::thread::{{impl}}::new::thread_start () at /checkout/src/libstd/sys/unix/thread.rs:90
#20 0x00007ffff2638184 in start_thread (arg=0x7fffe5bff700) at pthread_create.c:312
#21 0x00007ffff7440ffd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb)
A-LLVM A-codegen C-bug

Most helpful comment

The assertion is triggered as this function receives a string reference with a length of 0 but assumes the input is at least 1 byte long and looks at the first byte (which likely won't cause any bad behaviour when compiled without assertions as calling substr on an empty length StringRef won't do anything, though it may still be an issue). It may be sufficient to add an extra check there to see if there is any data in the string. Though trying to access an symbol with an empty name seems a bit suspicious though, granted I'm not familiar with the internals of LLVM, and it's a bit hard to debug.

All 14 comments

cc @alexcrichton The crash is in ThinLTO code.

@alexcrichton presumably this crashes without enabling ThinLTO and I cannot use the fuzzer without downgrade now. Would you investigate?

@ishitatsuyuki ThinLTO is automatically enabled recently. Does it work if you set the number of codegen-units to 1?

Sorry yes, that was it.

@alexcrichton turns out this is critical; codegen-units=1 doesn't help at all. Can anybody else confirm?

is it possible that this would be resolved by https://github.com/rust-lang/rust/pull/45810 ?

@frewsxcv maybe, but turning abort into UB is not a good idea.

The assertion that is triggered is a bounds check for a string reference, so disabling it would mean going out of bounds instead, which is likely a very bad idea.

related issue about the leak sanitizer breaking with ThinTLO: https://github.com/rust-lang/rust/issues/46126

The assertion is triggered as this function receives a string reference with a length of 0 but assumes the input is at least 1 byte long and looks at the first byte (which likely won't cause any bad behaviour when compiled without assertions as calling substr on an empty length StringRef won't do anything, though it may still be an issue). It may be sufficient to add an extra check there to see if there is any data in the string. Though trying to access an symbol with an empty name seems a bit suspicious though, granted I'm not familiar with the internals of LLVM, and it's a bit hard to debug.

This issue and #46126 might have been fixed by #50684 -- based on the trace, I'd guess that lack of the anon naming pass was the cause. I don't have a build with LLVM assertions handy to test.

I have a build, I'll try out and report back later.

I have confirmed that this doesn't seem to happen on master. Closing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

withoutboats picture withoutboats  路  211Comments

nikomatsakis picture nikomatsakis  路  274Comments

thestinger picture thestinger  路  234Comments

withoutboats picture withoutboats  路  308Comments

nikomatsakis picture nikomatsakis  路  340Comments