Skip to content

Allow specifying stack size of threads spawned by the test runner #111897

Open
@Fuuzetsu

Description

@Fuuzetsu

On platforms where concurrency is available, the test runner will always spawn threads with their default stack size:

let cfg = thread::Builder::new().name(name.as_slice().to_owned());

There appears to be no way to control this stack size without altering the default stack size of the code running within the test, via RUST_MIN_STACK.

The default rustc stack size for main thread is currently 8MiB:

const STACK_SIZE: usize = 8 * 1024 * 1024;

I think for spawned threads it's whatever the platform default is: I think on my Linux box this is 2MiB.

Consider that I have two pieces of code: one using 1MiB of stack size, usually running on a thread. Another piece of code using 6MiB usually running on main thread, possibly spawning the 1MiB one.

I now have a #[test]. When I run it, I get a stack overflow because we've spawned a thread with 2MiB to run the 6MiB stack code.

What are my options? It seems RUST_MIN_STACK is my only option, so I set it to, say, 8MiB to match the main thread stack.

This makes the test pass.

However now originally-1MiB stack code changes and stack usage to 3MiB! The test is still passing but the code is going to crash outside of tests: we've changed the behaviour of the code we are trying to verify is working because we're trying to work-around the test runner.

RUST_MIN_STACK is too big of a hammer: we should either have a way to specify the stack size for the test threads or pick a better default. It seems that the sanest default is the value of fn get_stack_size(). Changing the behaviour of code under testing just to control test runner seems very undesirable.

For people using RUST_MIN_STACK today, the behaviour remains the same. For people not using it, the memory usage of each test thread goes from their system default to the main-thread default. I think this is probably not a big deal for test runner. Indeed, if the program spawns any real number of threads, it might actually bring overall memory usage down.

PS: setting --test-threads 1 doesn't help: it still spawns a single thread with the same problem. It seems that platforms that don't support concurrency are the only way to run tests truly "sequentially".

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-libtestArea: `#[test]` / the `test` libraryC-feature-requestCategory: A feature request, i.e: not implemented / a PR.

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions