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

ICE: index out of bounds in librustc_span/hygiene.rs possibly caused by LTO #71639

Closed
Vlad-Shcherbina opened this issue Apr 28, 2020 · 5 comments · Fixed by #72625
Closed

ICE: index out of bounds in librustc_span/hygiene.rs possibly caused by LTO #71639

Vlad-Shcherbina opened this issue Apr 28, 2020 · 5 comments · Fixed by #72625
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Vlad-Shcherbina
Copy link

To reproduce

Run the following commands:

git clone https://github.com/Vlad-Shcherbina/rusty_sand.git
cd rusty_sand
git checkout e8a2513
RUST_BACKTRACE=1 cargo build --release

Meta

rustc --version --verbose:

binary: rustc
commit-hash: 2d03399f53d28a8be645625376c0c9fbe601a01d
commit-date: 2020-04-27
host: x86_64-unknown-linux-gnu
release: 1.45.0-nightly
LLVM version: 9.0

Error output

thread 'rustc' panicked at 'index out of bounds: the len is 30 but the index is 122', src/librustc_span/hygiene.rs:181:9
Backtrace

   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1069
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1504
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:481
  12: rust_begin_unwind
             at src/libstd/panicking.rs:385
  13: core::panicking::panic_fmt
             at src/libcore/panicking.rs:89
  14: core::panicking::panic_bounds_check
             at src/libcore/panicking.rs:65
  15: rustc_span::hygiene::HygieneData::expn_data
  16: scoped_tls::ScopedKey<T>::with
  17: rustc_codegen_ssa::back::write::SharedEmitterMain::check
  18: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::join_codegen
  19: rustc_interface::queries::Linker::link
  20: rustc_interface::interface::run_compiler_in_existing_thread_pool
  21: scoped_tls::ScopedKey<T>::set
  22: rustc_ast::attr::with_globals

Speculation

This could be related to LTO, because the bug was triggered when I added

[profile.release]
codegen-units = 1
lto = true

to my Cargo.toml.

@Vlad-Shcherbina Vlad-Shcherbina added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 28, 2020
@jonas-schievink jonas-schievink added E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example requires-nightly This issue requires a nightly compiler in some way. labels Apr 28, 2020
@steffahn
Copy link
Member

steffahn commented Apr 29, 2020

Minimal Example

Cargo.toml

[package]
name = "asm_error"
version = "0.1.0"
edition = "2018"

# this causes a bug
[profile.release]
codegen-units = 1
lto = true

lib.rs

#![feature(llvm_asm)]
pub struct S;
pub fn f() {
    unsafe { llvm_asm!( "call [rsi + 8*rax]" : : "rbx"(&S) : : "intel" ) };
}

main.rs

fn main() { asm_error::f() }

@rustbot modify labels: -E-needs-mcve


Compile with cargo +nightly build --release.

Backtrace:
thread 'rustc' panicked at 'index out of bounds: the len is 2 but the index is 2', src/librustc_span/hygiene.rs:181:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1069
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1504
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:515
  12: rust_begin_unwind
             at src/libstd/panicking.rs:419
  13: core::panicking::panic_fmt
             at src/libcore/panicking.rs:111
  14: core::panicking::panic_bounds_check
             at src/libcore/panicking.rs:69
  15: rustc_span::hygiene::HygieneData::expn_data
  16: rustc_span::hygiene::HygieneData::with
  17: rustc_codegen_ssa::back::write::SharedEmitterMain::check
  18: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::join_codegen
  19: rustc_interface::queries::Linker::link
  20: rustc_interface::interface::run_compiler_in_existing_thread_pool
  21: scoped_tls::ScopedKey<T>::set
  22: rustc_ast::attr::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.44.0-nightly (b2e36e6c2 2020-04-22) running on x86_64-unknown-linux-gnu

note: compiler flags: -C opt-level=3 -C lto -C codegen-units=1 --crate-type bin

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
end of query stack
error: could not compile `asm_error`.

@rustbot rustbot removed the E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example label Apr 29, 2020
@jonas-schievink jonas-schievink added the A-inline-assembly Area: Inline assembly (`asm!(…)`) label Apr 29, 2020
@fanninpm
Copy link

In my effort to add this to the glacier, I found that I'm having trouble replicating this on the latest nightly. Has this been fixed on your end?

@Vlad-Shcherbina
Copy link
Author

Yes, I'm able to reproduce the ICE with the minimal example by steffahn.

> rustc --version --verbose
rustc 1.45.0-nightly (bad3bf622 2020-05-09)
binary: rustc
commit-hash: bad3bf622bded50a97c0a54e29350eada2a3a169
commit-date: 2020-05-09
host: x86_64-pc-windows-msvc
release: 1.45.0-nightly
LLVM version: 9.0

@fanninpm
Copy link

Thanks! It turns out the problem was on my end, and now I'm able to get it to ICE.

@Amanieu
Copy link
Member

Amanieu commented May 24, 2020

Clang apparently does not set an inline asm diagnostic handler when running in LTO mode.

LLVM only allows us to attach a single integer to the inlineasm instruction as the source location. This works well in normal compilation since we can easily map that integer back to a Span to use for error reporting.

However with LTO we don't have the span data for any dependencies, only the root crate, so this doesn't work. I think we should emulate clang's behavior and disable the inline asm diagnostic handler in LTO mode.

RalfJung added a commit to RalfJung/rust that referenced this issue May 30, 2020
Improve inline asm error diagnostics

Previously we were just using the raw LLVM error output (with line, caret, etc) as the diagnostic message, which ends up looking rather out of place with our existing diagnostics.

The new diagnostics properly format the diagnostics and also take advantage of LLVM's per-line `srcloc` attribute to map an error in inline assembly directly to the relevant line of source code.

Incidentally also fixes rust-lang#71639 by disabling `srcloc` metadata during LTO builds since we don't know what crate it might have come from. We can only resolve `srcloc`s from the currently crate since it indexes into the source map for the current crate.

Fixes rust-lang#72664
Fixes rust-lang#71639

r? @petrochenkov

### Old style

```rust
#![feature(llvm_asm)]

fn main() {
    unsafe {
        let _x: i32;
        llvm_asm!(
            "mov $0, $1
             invalid_instruction $0, $1
             mov $0, $1"
             : "=&r" (_x)
             : "r" (0)
             :: "intel"
        );
    }
}
```

```
error: <inline asm>:3:14: error: invalid instruction mnemonic 'invalid_instruction'
             invalid_instruction ecx, eax
             ^~~~~~~~~~~~~~~~~~~

  --> src/main.rs:6:9
   |
6  | /         llvm_asm!(
7  | |             "mov $0, $1
8  | |              invalid_instruction $0, $1
9  | |              mov $0, $1"
...  |
12 | |              :: "intel"
13 | |         );
   | |__________^
```

### New style

```rust
#![feature(asm)]

fn main() {
    unsafe {
        asm!(
            "mov {0}, {1}
             invalid_instruction {0}, {1}
             mov {0}, {1}",
            out(reg) _,
            in(reg) 0i64,
        );
    }
}
```

```
error: invalid instruction mnemonic 'invalid_instruction'
 --> test.rs:7:14
  |
7 |              invalid_instruction {0}, {1}
  |              ^
  |
note: instantiated into assembly here
 --> <inline asm>:3:14
  |
3 |              invalid_instruction rax, rcx
  |              ^^^^^^^^^^^^^^^^^^^
```
@bors bors closed this as completed in fadfcb6 May 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants