Stack overflow when compiling on Windows 10

I have this code snippet here:

    #![allow(non_snake_case)]
    #[allow(dead_code)]
    #[derive(Copy,Clone)]
    struct Node {
        traversed: i32,
        ended: i32,
        up: i32,
        down: i32,
        left: i32,
        right: i32,
    }
    const WIDTH: usize=200;
    const HEIGHT: usize=300;

    fn main() {


        let mut arr= [[Node{ traversed: 0, ended: 0,
            up: 0,
            down: 0,
            left: 0,
            right: 0
        }; HEIGHT]; WIDTH];
        arr[0][0].traversed=69;
        println!("{}",arr[0][0].traversed);
        
    }

Which compiles fine on Rust Playground. However, for whatever reason, when compiling on Windows 10, I get the error "thread 'main' has overflowed its stack".


Is there any further configuration or adjustment I should make on Windows 10 or the Cargo.toml file? Thank you

I have little experience of Windows programming but I would be loath to declare megabyte and a half of array on the stack like that anywhere.

Note: The stack overflow happens when running the program, not when compiling it.

This happens because arr takes up about 1.4 MB of stack space. Limits on stack space are different on different machines and platforms, but generally it's a good idea to store large values (hundreds of KB or larger) on the heap. You can do this by changing arr from an array to a Vec:

    let mut arr= vec![[Node{ traversed: 0, ended: 0,
        up: 0,
        down: 0,
        left: 0,
        right: 0
    }; HEIGHT]; WIDTH];
1 Like

Awesome. Thank you.

Sound fair to me :smiley:

Note that on Windows you can set your applications stack size using a linker flag. Oddly Rust sticks with the fallback value of 1 MiB for the main thread but (by default) sets it to 2 MiB when creating threads.

But yes, the heap is always preferable for large values.

Can you specify how to flag it, the syntax that is. I am new, so this might come in handy.

Sure. But it depends on the linker. For the msvc toolchain it's something like /STACK:8000000 which will set the stack to 8 megabytes. For the gnu toolchain it's --stack 8000000 (took me awhile to find where that's documented).

Setting this in Rust is a bit awkward. You need to create a folder in the root of your project directory called ".cargo" and then add a file to it called "config.toml". In that file you can set custom linker options:

# 64 bit MSVC
[target.x86_64-pc-windows-msvc]
rustflags = [
	"-C", "link-arg=/STACK:8000000"
]

# 64 bit Mingw
[target.x86_64-pc-windows-gnu]
rustflags = [
    "-C", "link-arg=-Wl,--stack,8000000"
]

edit: changed mingw linker format because mingw makes it surprisingly hard to pass linker arguments.

4 Likes

Awesome info. Thank you.

Since stack space is determined by the compiler, atleast it can warn when more stack space being used in the function. I don't understand since the size atleast can be already determined here at compile time. In other compilers(like gcc) also dont give warning for allocating this much space.

This is platform dependent. On some OSes it's defined by the linker but on other it's set only by the OS. So Rust can't always know how much stack space you have. EDIT: Clippy does have a warning for large stack arrays.

Btw, if you do want to control the stack size in a more cross-platform way then it's better to build a new thread.using the stack_size option.

1 Like