Skip to content

Windows 7 i686 does not reliably align 16 byte aligned thread locals #138903

Closed
@drewkett

Description

@drewkett

The following program will reliably crash using the i686-win7-windows-msvc target on a Windows 7 installation using latest nightly.

I tried this code:

#[repr(align(16))]
struct Align16(u8);

thread_local! {
    static ALIGN16: Align16 = Align16(0);
}

fn main() {
    let mut threads = Vec::new();
    for _ in 0..10 {
        threads.push(std::thread::spawn(|| {
            ALIGN16.with(|r| println!("ALIGN16 {:p}", r as *const _));
        }));
    }
    for thread in threads {
        thread.join().unwrap();
    }
}

This reliably produces the following panic.

unsafe precondition(s) violated: ptr::replace requires that the pointer argument is aligned and non-null

This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused a non-unwinding panic. aborting.

My experience with/understanding of thread locals is mostly limited to what i've researched due to this issue, but it does appear that an i686 targeted executable on Windows 7 does not reliably align thread locals when 16 byte alignment is requested. I didn't see issues with even 8 byte alignment. I was not able to reproduce this issue on Windows 10.

Given that i686 win7 is a likely pretty niche target, do you think it would be reasonable to partially undo #123257 by disabling has_thread_local for i686-win7-windows-msvc. It seems that i686 on Windows 7 can't be trusted for alignment of thread locals. I did test adjusting the i686-win7-windows-msvc target in a local build of the compiler and it does appear to work for the test program.

The 16 byte aligned thread local came from matrixmultiply which actually works around misalignment internally, but compiled this way I get the UB check panic anyway. I can certainly work around it by seeing if matrixmultiply can be patched, or just doing that locally. But it seems like this should be fixed in the compiler ideally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-alignArea: alignment control (`repr(align(N))` and so on)A-thread-localsArea: Thread local storage (TLS)C-bugCategory: This is a bug.O-windows-7OS: Windows 7 or Windows Server 2008 R2 or etc.O-x86_32Target: x86 processors, 32 bit (like i686-*) (IA-32)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions