Byron
Byron

Reputation: 4316

How to set the thread stack size during compile time?

When attempting to run a program that builds a large clap::App (find the source here), I get a stackoverflow: thread '<main>' has overflowed its stack.

So far I was unable to figure out how to instruct rustc to increase the stacksize for a brute-force workaround. RUST_MIN_STACK seems to apply only to runtime, and even there it didn't seem to have any effect.

As the code is generated, what I would probably have to do is to move the SubCommand creation to the runtime, which is what I will try next.

However, do you see a way to fix this differently ?

It seems quite important to figure this one out as the builder patterns appears to be prone to this issue, if the built structure is just large and nested enough.

How to reproduce

git clone -b clap https://github.com/Byron/google-apis-rs
cd google-apis-rs
git checkout 9a8ae4b
make dfareporting2d1-cli-cargo ARGS=run

Please note that you will need my fork of quasi and set an override locally to allow building with the latest compiler.

Meta

➜  google-apis-rs git:(clap) rustc --version
rustc 1.1.0-nightly (97d4e76c2 2015-04-27) (built 2015-04-28)

Upvotes: 16

Views: 7070

Answers (1)

planetbeing
planetbeing

Reputation: 358

There's no way to set the stack size of the main thread in Rust. In fact, an assumption about the size of the main thread's stack is made at the source code level in the Rust runtime library (https://github.com/rust-lang/rust/blob/master/src/libstd/rt/mod.rs#L85).

The environment variable RUST_MIN_STACK influences the stack size of threads created within the program that's not the main thread, but you could just as easily specify that value within your source code at runtime.

The most straightforward way to solve your problem might be to run the clap in a separate thread you create, so that you can control its stack size.

Take this code for example:

extern crate clap;
use clap::App;
use std::thread;

fn main() {
    let child = thread::Builder::new().stack_size(32 * 1024 * 1024).spawn(move || {
        return App::new("example")
            .version("v1.0-beta")
            .args_from_usage("<INPUT> 'Sets the input file to use'")
            .get_matches();
    }).unwrap();

    let matches = child.join().unwrap();

    println!("INPUT is: {}", matches.value_of("INPUT").unwrap());
}

clap appears to be able to terminate the application correctly from within the child thread so your code should work with little modification.

Upvotes: 20

Related Questions