Skip to content

large stack arrays cause segfaults in safe code (even with ulimit unlimited) #34877

Closed
@m4b

Description

@m4b

Note, first make sure to set ulimit -s unlimited before running the program below.

Something like the following has problems with bad ASM stack offsets/accesses being generated due to 32-bit overflow.

Looks like this is something known in LLVM: https://groups.google.com/forum/#!topic/llvm-dev/g4sF46a47_w

This also only seems to cause segfaults in --release mode

Note however, it's not entirely clear how to easily get a directly heap allocated, large fixed size array without resorting to unsafe, box syntax, or using the vec hack.

I suspect this will come up often as a result, since many people and beginners will attempt to stack allocate a large object only to have it segfault.

Various values can be tweaked to make it not segfault in release or debug, in an entirely unintuitive way, which lends the language a less user friendly feeling, along with violating the principle of least surprise in many cases, imho.

#![feature(box_syntax)]

use std::ops::Index;
use std::ops::IndexMut;
use std::boxed::Box;

// causes problems
//const SIZE: usize = 1300;
const SIZE: usize = 1255;
const BOUND: usize = SIZE;
pub const ARR_SIZE: usize = SIZE * SIZE * BOUND;

struct Arr {
    arr: [[[u8; SIZE]; SIZE]; BOUND]
}

impl Arr {
    pub fn create () -> Arr {
        let x = [0u8; SIZE];
        let y = [x; SIZE];
        let z = [y; BOUND];
// won't cause problems in release
//        Arr { arr: [[[1u8; SIZE]; SIZE]; SIZE] }
        Arr { arr: z }
    }
}

impl Index<usize> for Arr {
    type Output = [[u8; SIZE]; SIZE];

    fn index(&self, _index: usize) -> &Self::Output {
        &self.arr[_index]
    }
}

impl IndexMut<usize> for Arr {
    fn index_mut(&mut self, _index: usize) -> &mut [[u8; SIZE]; SIZE] {
        &mut self.arr[_index]
    }
}

fn main() {
// let mut arr = box Arr::create();
    let mut arr = Arr::create();

    for i in 0..BOUND {
        for j in 0..SIZE {
            for k in 0..SIZE {
                arr[i][j][k] = (i+j+k) as u8;
            }
        }
    }
/*
    for i in 0..SIZE {
        for j in 0..SIZE {
            for k in 0..SIZE {
                println!("{}", arr[i][j][k])
            }
        }
    }
*/
    println!("res: {}", arr[1][0][0]);
    println!("res: {}", arr[1][SIZE-1][SIZE-1]);
    println!("res: {}", arr[1][SIZE-1][SIZE-1]);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.I-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions