profile
viewpoint

Ask questionsIncorrect compilation / STATUS_ACCESS_VIOLATION when linking with lld with target-cpu set

The compilation of crates fails in various ways when a certain combination of rustflags is set.

[build]
rustflags = [
	"-Clinker-flavor=lld-link",
	"-Ctarget-cpu=sandybridge"
]

With this configuration I encountered the following issues:

  • During installation of the sd crate (version 0.7.5), rustc crashes with a STATUS_ACCESS_VIOLATION. See the detailled error output below.
  • When installing starship, the resulting binary doesn't work correctly (see the issue here).

Using each rustflag individually does not result in this issue. I could reproduce this both on stable and the recent nightly, and with target-cpu set to either sandybridge, haswell or znver2 (without trying more).

Meta

rustc --version --verbose:

rustc 1.45.0-nightly (99cb9ccb9 2020-05-11)
binary: rustc
commit-hash: 99cb9ccb9ca2067ad6e60508e3d52da77396b2f1
commit-date: 2020-05-11
host: x86_64-pc-windows-msvc
release: 1.45.0-nightly
LLVM version: 9.0

<!-- Include a backtrace in the code block by setting RUST_BACKTRACE=1 in your environment. E.g. RUST_BACKTRACE=1 cargo build. --> <details><summary>Error during cargo install --force sd</summary> <p>

❯ cargo install --force sd
    Updating crates.io index
  Installing sd v0.7.5
   Compiling proc-macro2 v1.0.12
   Compiling autocfg v1.0.0
   Compiling unicode-xid v0.2.0
   Compiling syn v1.0.20
   Compiling cfg-if v0.1.10
   Compiling lazy_static v1.4.0
   Compiling version_check v0.9.1
   Compiling winapi v0.3.8
   Compiling getrandom v0.1.14
   Compiling maybe-uninit v2.0.0
   Compiling bitflags v1.2.1
   Compiling unicode-width v0.1.7
   Compiling libc v0.2.70
   Compiling unicode-segmentation v1.6.0
   Compiling scopeguard v1.1.0
   Compiling memchr v2.3.3
   Compiling vec_map v0.8.2
   Compiling strsim v0.8.0
   Compiling roff v0.1.0
   Compiling rayon-core v1.7.0
   Compiling ppv-lite86 v0.2.6
   Compiling either v1.5.3
   Compiling regex-syntax v0.6.17
   Compiling unescape v0.1.0
   Compiling thread_local v1.0.1
   Compiling textwrap v0.11.0
   Compiling man v0.3.0
   Compiling heck v0.3.1
   Compiling crossbeam-utils v0.7.2
   Compiling memoffset v0.5.4
   Compiling crossbeam-epoch v0.8.2
   Compiling rand_core v0.5.1
   Compiling proc-macro-error-attr v1.0.2
   Compiling proc-macro-error v1.0.2
   Compiling aho-corasick v0.7.10
   Compiling num_cpus v1.13.0
   Compiling rand_chacha v0.2.2
   Compiling quote v1.0.4
   Compiling rand v0.7.3
   Compiling crossbeam-queue v0.2.1
   Compiling crossbeam-deque v0.7.3
   Compiling rayon v1.3.0
   Compiling regex v1.3.7
   Compiling syn-mid v0.5.0
   Compiling atty v0.2.14
   Compiling remove_dir_all v0.5.2
   Compiling memmap v0.7.0
   Compiling clap v2.33.1
   Compiling tempfile v3.1.0
   Compiling thiserror-impl v1.0.16
   Compiling structopt-derive v0.4.7
   Compiling thiserror v1.0.16
   Compiling structopt v0.3.14
   Compiling sd v0.7.5
error: failed to compile `sd v0.7.5`, intermediate artifacts can be found at `C:\Users\Chris\AppData\Local\Temp\cargo-installLldcG5`

Caused by:
  could not compile `sd`.

Caused by:
  process didn't exit successfully: `rustc --crate-name build_script_build --edition=2018 C:\Users\Chris\.cargo\registry\src\github.com-1ecc6299db9ec823\sd-0.7.5\build.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C opt-level=3 -Cembed-bitcode=no -C codegen-units=1 -C metadata=a9d539b504a5dcff -C extra-filename=-a9d539b504a5dcff --out-dir C:\Users\Chris\AppData\Local\Temp\cargo-installLldcG5\release\build\sd-a9d539b504a5dcff -L dependency=C:\Users\Chris\AppData\Local\Temp\cargo-installLldcG5\release\deps --extern man=C:\Users\Chris\AppData\Local\Temp\cargo-installLldcG5\release\deps\libman-415ee6d25251500d.rlib --extern structopt=C:\Users\Chris\AppData\Local\Temp\cargo-installLldcG5\release\deps\libstructopt-75fe88c87a7c5329.rlib --cap-lints allow -Clinker-flavor=lld-link -Ctarget-cpu=sandybridge` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)

</p> </details>

Also possibly relevant for #71520.

rust-lang/rust

Answer questions luqmana

Looks like it's reading a value from TLS and adding an offset to use as a pointer that is not 32-byte aligned (0x000002104d54ced0):

00007ffd`9ac9dfdb 8b0517321700         mov     eax, dword ptr [structopt_derive_afd65372c61b620b!_tls_index (00007ffd`9ae111f8)]
00007ffd`9ac9dfe1 65488b0c2558000000   mov     rcx, qword ptr gs:[58h]
00007ffd`9ac9dfea 488b0cc1             mov     rcx, qword ptr [rcx+rax*8]
00007ffd`9ac9dfee c5fc288120000000     vmovaps ymm0, ymmword ptr [rcx+20h] ds:00000210`4d54ced0=00
00007ffd`9ac9dff6 4883b92000000000     cmp     qword ptr [rcx+20h], 0
00007ffd`9ac9dffe c5fc280d5a051100     vmovaps ymm1, ymmword ptr [structopt_derive_afd65372c61b620b!_ymm (00007ffd`9adae560)]
00007ffd`9ac9e006 488b8130000000       mov     rax, qword ptr [rcx+30h]

This is happening in the proc_macro_error::dummy::set_dummy call which tries to read/write a thread local:

thread_local! {
    static DUMMY_IMPL: RefCell<Option<TokenStream>> = RefCell::new(None);
}

LLVM seems to believe it should be 32 byte aligned, but as far as I can tell when ntdll is allocating the TLS slots they're 16 byte aligned

@_ZN16proc_macro_error5dummy10DUMMY_IMPL7__getit5__KEY17h4a7e8c80e38ac6e5E = internal thread_local global <{ [64 x i8] }> zeroinitializer, align 32

Sounds like a similar issue to https://github.com/rust-lang/rust/issues/44056

When built with lld-link there's no alignment specified for the TLS section in the DLL:

Dump of file structopt_derive-afd65372c61b620b.dll

File Type: DLL

  Section contains the following TLS directory:

    0000000180229000 Start of raw data
    0000000180229148 End of raw data
    00000001801E11F8 Address of index
    000000018019C3B0 Address of callbacks
                   0 Size of zero fill
            00000000 Characteristics
                       (no align specified)

But using the default msvc linker instead results in the correct alignment:

Dump of file structopt_derive-afd65372c61b620b.dll

File Type: DLL

  Section contains the following TLS directory:

    000000018019D960 Start of raw data
    000000018019DAA8 End of raw data
    00000001801E2278 Address of index
    000000018017D248 Address of callbacks
                   0 Size of zero fill
            00600000 Characteristics
                       32 byte align

Seems like an LLD bug?

useful!

Related questions

Spurious NaNs produced by trig functions with valid inputs on Windows GNU toolchains hot 3
using 'cargo install xsv' on windows 10 triggers rustc internal error hot 2
under latest MinGW, cannot link with C code using stdout hot 2
Archive all nightlies hot 2
chain() make collect very slow hot 1
if/while Some(n) = &mut foo sugar will leak a temporary mutable borrow to current scope in particular situation hot 1
build an empty project failed (undefined reference to `__onexitbegin') hot 1
Invalid collision with TryFrom implementation? hot 1
Crater runs for Rust 1.38.0 hot 1
Spurious NaNs produced by trig functions with valid inputs on Windows GNU toolchains hot 1
Building LLVM with Clang fails hot 1
Internal compiler error: can't buffer lints after HIR lowering hot 1
E0373 help suggests `move async` but the correct syntax is `async move` hot 1
Tracking issue for `Option::contains` and `Result::contains` hot 1
async fn + rustfmt don't "just work" inside of RLS hot 1
source:https://uonfu.com/
Github User Rank List