esp-rs / rust

Rust for the xtensa architecture. Built in targets for the ESP32 and ESP8266
https://www.rust-lang.org
Other
743 stars 39 forks source link

Stack overflow when sleeping on ESP32-S2 with multiple prints/HAL #90

Closed emmabritton closed 2 years ago

emmabritton commented 3 years ago

I'm not sure where the bug is, and so I'm not this is the right repo to raise this.

I tried this code:

use std::thread;
use std::time::Duration;
use esp_idf_hal::prelude::*;
use esp_idf_sys;

fn main() {
    esp_idf_sys::link_patches();

    let peripherals = Peripherals::take().unwrap();
    let pins = peripherals.pins;

    let mut p18 = pins.gpio10.into_output().unwrap();

    println!("before");

    println!("mid");

    thread::sleep(Duration::from_secs(1));

    println!("after");
}

Full project at https://github.com/raybritton/esp32-rust-bug

I expected to see this happen: The execution should pause for 1 second

Instead, this happened: A stack overflow is detected and the device reboots infinitely.

If println!("mid"); or println!("before"); or let perip...put().unwrap(); is commented out the code works correctly.

Meta

rustc --version --verbose:

rustc 1.56.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-apple-darwin
release: 1.56.0-dev
LLVM version: 12.0.1

The output from monitor can be seen at https://pastebin.com/fAXsfRgj

I've tried with two ESP32-S2-Soala-1_v1.2 boards from https://eu.mouser.com/ProductDetail/espressif/esp32-s2-saola-1r and get the same results.

MabezDev commented 3 years ago

The main task stacksize by default is pretty small, perhaps try increasing to say 8192 bytes.

CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 inside your sdkconfig.defaults file.

mladedav commented 2 years ago

Similar stuff happens to me too. What's weird about it is that the stack overflow occurs early if there is a function call in main. If I comment out the call the stack overflow does not happen but control never gets inside the function.

Adding the main task stack size line into sdkconfig doesn't seem to change anything.

MabezDev commented 2 years ago

Similar stuff happens to me too. What's weird about it is that the stack overflow occurs early if there is a function call in main. If I comment out the call the stack overflow does not happen but control never gets inside the function.

The function probably gets inlined into main, then causing the stack overflow. You can try increasing the stack further or running your other big operation in a new thread.

ryanc-me commented 2 years ago

Similar issue here also.

I have a function that writes TCP packets out via a TcpStream, using a buffer of &[u8]. With the function included in main, even right at the end, my app crashes almost immediately. The issue doesn't occur if the function is commented out.

Oddly, the &[u8] buffer is only 512 bytes, but even raising the stack size by tens of kilobytes does not help.

I tried:

In the end, spawning a new thread with 16KB stack was the only thing that worked. Thanks @MabezDev!

MabezDev commented 2 years ago

FYI you might be able to analyze the stack size of your functions with https://github.com/japaric/stack-sizes.

Closing for now.