Rust program overflows stack, but not in benchmarks

I'm writing a programming language and I have a simple program that loops 5,000,000 times. This causes a stack overflow when I run the program through my binary with cargo run. However, the benchmark that runs the exact same function using criterion does not cause a stack overflow.

Why is this happening? To be clear, I understand why the stack overflow is happening, I'm just wandering what it is that makes the benchmark case different so as to prevent the overflow.

By default benchmarks are compiled with optimizations enabled, more akin to what cargo run --release does. Some optimization likely reduced the amount of stack space needed, if not entirely removed your code if it was doing nothing

The stack overflow also happens when I run it in release mode. I also tried commenting out my changes to the release profile in Cargo.toml but it didn't help.

could be that criterion uses other optimization options?

If you tell us more about exactly why it is happening, someone may be able to give you a better answer.

The stack overflows because the language's VM is using a kind of threaded code that relies on recursive tail calls.

As you may know, the tail recursion optimization isn't guaranteed in Rust, meaning the normal practice is to only use a fairly small maximum number of recursions.

I realize your question is why your test sometimes works and sometimes doesn't, but really the only reliable option is to assume the optimization is not used, and limit the number of recursions according to what is placed on the stack and the stack size.

I am aware of the lack of tail call optimization in Rust and I am aware of so-called "stackless" options for writing the VM that would not need to worry about stack overflows. Again, I'm looking for information on why the stack overflow does not happen when benchmarking.

1 Like

Well, without a repro people would just be guessing. Share code.

Criterion does different things with your code than just running the function, like looping it, black boxing, and warmup, which is probably enough to change the stack layout. There's nothing super special about it though, so you'll probably run into the stack overflow in benchmarks when you change some code anyway.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.