esp-rs / rust

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

Float Variable Assignment in C Triggers ESP C3 Panic #176

Closed elotom closed 1 year ago

elotom commented 1 year ago

I'm binding a Rust function to a C function that uses floating point operations. When the float/double variable is set to the value != 0 I got a panic (Illegal instruction) exception. I'm using ESP32-C3-DEVKITC-02. I checked both idf releases 4.4 and 5.0 with the same result. My project code works fine on esp32S3.

To reproduce the issue please clone https://github.com/elotom/rust-esp32-std-demo/tree/c-float-panic-issue then run the following commands:

  1. riscv32-esp-elf-gcc -llibtest_float -o c/test_float.o -c c/test_float.c
  2. riscv32-esp-elf-ar csrDT c/libtest_float.a -c c/test_float.o
  3. Flash your device with cargo +esp espflash --target riscv32-esp32-espidf --monitor

The C function only sets 1 to the float value. The same issue occurs for double variables.

void test_float()
{
    float val = 1;
}

The Rust function calls test_float() and the program panic:

Core  0 register dump:
MEPC    : 0x42000144  RA      : 0x42000034  SP      : 0x3fc92d50  GP      : 0x3fc8a800  
0x42000144 - 
    at ??:??
0x42000034 - rust_esp32_std_demo::main
    at /home/tomek/Projects/Github/rust-esp32-std-demo/src/main.rs:417
TP      : 0x3fc6b720  T0      : 0x42043fce  T1      : 0x0000000f  T2      : 0x00000000  
0x42043fce - std::thread::local::os::Key<T>::try_initialize
    at /home/tomek/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/thread/local.rs:1127
S0/FP   : 0x3fc92d70  S1      : 0x3c070120  A0      : 0x00000000  A1      : 0x42000172  
0x42000172 - lstat
    at /home/tomek/.cargo/registry/src/github.com-1ecc6299db9ec823/esp-idf-sys-0.32.1/src/patches/lstat.rs:13
A2      : 0x00000002  A3      : 0x3fc937e4  A4      : 0x3fc937e4  A5      : 0x3c070000  
A6      : 0x00000000  A7      : 0x807fffff  S2      : 0x00000000  S3      : 0x00000000  
S4      : 0x00000000  S5      : 0x00000000  S6      : 0x00000000  S7      : 0x00000000  
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000  
T3      : 0x00020000  T4      : 0x00000000  T5      : 0x00000000  T6      : 0x00000000  
MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000002  MTVAL   : 0x1507a787  
0x40380001 - _iram_start
    at ??:??
MHARTID : 0x00000000  
Stack memory:
3fc92d50: 0x00000000 0x3fc8c320 0x00001800 0x403819c2 0x00000000 0x00000000 0x00000000 0x3fc92dc8
0x403819c2 - heap_caps_malloc_base
    at /home/tomek/Projects/Github/rust-esp32-std-demo/.embuild/espressif/esp-idf/release-v4.4/components/heap/heap_caps.c:176
3fc92d70: 0x00000000 0x00000000 0x3fc92dc8 0x420000ba 0x00001800 0x0000000c 0x00000000 0x42000088
0x420000ba - std::sys_common::backtrace::__rust_begin_short_backtrace
    at /home/tomek/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:127
0x42000088 - std::rt::lang_start::{{closure}}
    at /home/tomek/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/rt.rs:166
3fc92d90: 0x00000000 0x3c070154 0x00000000 0x4202bab2 0x00000000 0x3fc8bbfc 0x00000000 0x3c070154
0x4202bab2 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
    at /home/tomek/.rustup/toolchains/esp/lib/rustlib/src/rust/library/core/src/ops/function.rs:286
3fc92db0: 0x00000000 0x00000000 0x00000000 0x42000074 0x00000000 0x00000000 0x42000020 0x42069be4
0x42000074 - std::rt::lang_start
    at /home/tomek/.rustup/toolchains/esp/lib/rustlib/src/rust/library/std/src/rt.rs:172
0x42000020 - rust_esp32_std_demo::main
    at /home/tomek/Projects/Github/rust-esp32-std-demo/src/main.rs:119
0x42069be4 - main_task
    at /home/tomek/Projects/Github/rust-esp32-std-demo/.embuild/espressif/esp-idf/release-v4.4/components/freertos/port/port_common.c:143
3fc92dd0: 0x00000000 0x00000000 0x00000000 0x40385afc 0x00000000 0x00000000 0x00000000 0x00000000
0x40385afc - _prvTaskExitError
    at /home/tomek/Projects/Github/rust-esp32-std-demo/.embuild/espressif/esp-idf/release-v4.4/components/freertos/port/riscv/port.c:126
3fc92df0: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc92e10: 0x00000154 0x3fc92d60 0x3fc8bc44 0x3fc8b62c 0x3fc8b62c 0x3fc92e14 0x3fc8b624 0x00000018
3fc92e30: 0x285126dd 0x2cbc92c5 0x3fc92e14 0x00000000 0x00000001 0x3fc8ddf0 0x6e69616d 0x61fd0700
3fc92e50: 0xe5e09288 0x00e8e2de 0x00000000 0x3fc92e00 0x00000001 0x00000000 0x3fc937ec 0x42058534
0x42058534 - pthread_local_storage_thread_deleted_callback
    at /home/tomek/Projects/Github/rust-esp32-std-demo/.embuild/espressif/esp-idf/release-v4.4/components/pthread/pthread_local_storage.c:129
3fc92e70: 0x00000000 0x3fc8c5f8 0x3fc8c660 0x3fc8c6c8 0x00000000 0x00000000 0x00000001 0x00000000
3fc92e90: 0x00000000 0x00000000 0x420600f8 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
0x420600f8 - _cleanup_r
    at /builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/newlib/newlib/libc/stdio/findfp.c:229
3fc92eb0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc92ed0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc92ef0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc92f10: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc92f30: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc92f50: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x3f000000 0x00000600 0xa5a5a5a5
3fc92f70: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc92f90: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc92fb0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc92fd0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc92ff0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc93010: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc93030: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc93050: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc93070: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc93090: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc930b0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc930d0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc930f0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc93110: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc93130: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
ELF file SHA256: 0000000000000000
Rebooting...
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xc (SPI_FAST_FLASH_BOOT)
Saved PC:0x40381256
0x40381256 - esp_restart_noos_dig
    at /home/tomek/Projects/Github/rust-esp32-std-demo/.embuild/espressif/esp-idf/release-v4.4/components/esp_system/esp_system.c:53
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x168c
load:0x403cc710,len:0x940
0x403cc710 - _coredump_iram_start
    at ??:??
load:0x403ce710,len:0x2e40
0x403ce710 - _coredump_iram_start
    at ??:??
SHA-256 comparison failed:
Calculated: 79fc641ba12316941cff423a71154a99e7e87ecefeba43edae22fea93f3d6d87
Expected: 00012691117a29e160429705642fcb50232179307765a11c4a5328bdfa8bb425
Attempting to boot anyway...
entry 0x403cc710
0x403cc710 - _coredump_iram_start
    at ??:??

rustc --version --verbose:

rustc 1.67.1 (d5a82bbd2 2023-02-07)
binary: rustc
commit-hash: d5a82bbd26e1ad8b7401f6a718a9c57c96905483
commit-date: 2023-02-07
host: x86_64-unknown-linux-gnu
release: 1.67.1
LLVM version: 15.0.6
elotom commented 1 year ago

Same for updated rustc: rustc 1.69.0-nightly (e7a099116 2023-04-17) (1.69.0.0) binary: rustc commit-hash: e7a0991164b497f97a9af93183eb4ea51d0f5c48 commit-date: 2023-04-17 host: x86_64-unknown-linux-gnu release: 1.69.0-nightly LLVM version: 15.0.0

I have checked the latest version also with the same result: rustc 1.69.0-nightly (4896f6b45 2023-05-16) (1.69.0.1) binary: rustc commit-hash: 4896f6b455b005c410fb7ef87a2f96bf5b1b73cb commit-date: 2023-05-16 host: x86_64-unknown-linux-gnu release: 1.69.0-nightly LLVM version: 16.0.1

Tested also the latest IDF-5.1 with gcc riscv32-esp-elf-gcc (crosstool-NG esp-12.2.0_20230208) 12.2.0 with the same result

MabezDev commented 1 year ago

This is most likely some ABI issue between GCC & LLVM, given that it's for a RISCV target this is probably worth posting upstream. They would most likely want it to be reproducible without hardware though.

You could try building esp-idf with clang and see if that helps. You can do this by installing the clang component via idf_tools.py install esp-clang and then setting the toolchain to clang via export IDF_TOOLCHAIN=clang.

elotom commented 1 year ago

This is most likely some ABI issue between GCC & LLVM, given that it's for a RISCV target this is probably worth posting upstream. They would most likely want it to be reproducible without hardware though.

You could try building esp-idf with clang and see if that helps. You can do this by installing the clang component via idf_tools.py install esp-clang and then setting the toolchain to clang via export IDF_TOOLCHAIN=clang.

Compiling my C sources with Clang fixed the issue.

MabezDev commented 1 year ago

In which case I'll close this! Hopefully upstream both GCC and CLANG soft float ABI converge towards eachother.

ivmarkov commented 7 months ago

@MabezDev Is building ESP-IDF with clang an officially (or semi-officially) supported option now?

MabezDev commented 7 months ago

@MabezDev Is building ESP-IDF with clang an officially (or semi-officially) supported option now?

I'm not sure on official, but I would guess semi-official, as in it should be doable. Expect more issues on Xtensa though (with regards to code size, last time I checked a clang built bootloader exceeded the 64KB allowance, but maybe that's changed.).

ivmarkov commented 7 months ago

Do you have any pointer to the upstream gcc/clang ABI mismatches? Are these only w.r.t. soft-float? Even so, sounds quite scary and weird. As in stuff compiled with clang cannot interop with stuff compiled with gcc...

MabezDev commented 7 months ago

I never found any upstream issues about it, and tbh, it was just a hunch on my end. It seemed to solve the issue for @elotom though, perhaps that can expand on thier findings.