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.

rustflags = [

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).


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 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\\sd-0.7.5\ --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.


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

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?


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
Github User Rank List