Closed bjoernQ closed 2 years ago
Interesting! I've seen this sort of thing a few times too but I can now reproduce using your example changes.
My exception info:
*** PanicInfo { payload: Any { .. }, message: Some(Exception: LoadProhibited, Context { PC: 400f5603, PS: 00060f30, A0: 800d7c51, A1: 3ffffa00, A2: 00000001, A3: 3fffff7c, A4: 800d9243, A5: 3ffff730, A6: 3ffb016c, A7: 00000013, A8: 800d803a, A9: 3ffff9c0, A10: 3fffff78, A11: 0000546c, A12: 8008376e, A13: 3ffff6e0, A14: 00000000, A15: 10200000, SAR: 00000010, EXCCAUSE: 0000001c, EXCVADDR: 00000001, LBEG: 40079161, LEND: 40079168, LCOUNT: 00000000, THREADPTR: 00000000, SCOMPARE1: 00000000, BR: 00000000, ACCLO: 00000000, ACCHI: 00000000, M0: 00000000, M1: 00000000, M2: 00000000, M3: 00000000, F64R_LO: 00000000, F64R_HI: 00000000, F64S: 00000000, FCR: 00000000, FSR: 00000000, F0: 00000000, F1: 00000000, F2: 00000000, F3: 00000000, F4: 00000000, F5: 00000000, F6: 00000000, F7: 00000000, F8: 00000000, F9: 00000000, F10: 00000000, F11: 00000000, F12: 00000000, F13: 00000000, F14: 00000000, F15: 00000000, reserved: [3ffffa60, 3ffffa64, 3ffffa68, 3fffff58, 3ffffa20, 3ffff9f0, 800d7c31], BASESAVE: [3ffffa30, 3fffff78, 0000546b, 0000546c] }), location: Location { file: "/home/mabez/.cargo/registry/src/github.com-1ecc6299db9ec823/xtensa-lx-rt-0.7.0/src/exception/lx6.rs", line: 95, col: 5 } }
Looking at the disassembly it points me here:
400f55fc <core::cmp::impls::<impl core::cmp::PartialOrd for i32>::lt>:
400f55fc: 006136 entry a1, 48
400f55ff: 2129 s32i.n a2, a1, 8 # <-- store value of a2 8 bytes offset from the stack pointer
400f5601: 3139 s32i.n a3, a1, 12 # <-- store value of a3 on stack too
400f5603: 0288 l32i.n a8, a2, 0 # <-- Offending line, try and load the value of the address in a2, into a8
400f5605: 0398 l32i.n a9, a3, 0
400f5607: 0a0c movi.n a10, 0
400f5609: 01a9 s32i.n a10, a1, 0
400f560b: 1a0c movi.n a10, 1
400f560d: 11a9 s32i.n a10, a1, 4
400f560f: 032897 blt a8, a9, 400f5616 <core::cmp::impls::<impl core::cmp::PartialOrd for i32>::lt+0x1a>
400f5612: 0188 l32i.n a8, a1, 0
400f5614: 1189 s32i.n a8, a1, 4
400f5616: 1128 l32i.n a2, a1, 4
400f5618: f01d retw.n
It's trying to load the value from the address in a2
(the third argument being an optional offset from the address in a2
). Looking at the exception context the address its trying to load from (in a2
) is 00000001
... which definitely does not look right (looks more like a value than and address)!
Seems very odd that its storing the argument values on the stack, and then trying to use the same argument register as the source address of a load...
It's also worth looking at the signature of core::cmp::PartialOrd
's lt
method: fn le(&self, other: &i32) -> bool
, these arguments should be passed by reference, not value.
I suspect this is probably a codegen bug.
If it helps, I found another way to trigger the exception without involving code from core:
I just add this to the example
fn wait() {
let mut c: i32 = 0;
loop {
let is_lower = lower(&c, &1_000_000);
if !is_lower {
break;
} else {
c += 1;
}
}
}
fn lower(a: &i32, b: &i32) -> bool {
*a < *b
}
And change the sleep to wait()
.
I get this exception info:
PanicInfo { payload: Any { .. }, message: Some(Exception: LoadProhibited, Context { PC: 400f536b, PS: 00060f30, A0: 800d9776, A1: 3ffffa70, A2: 00000001, A3: 3f400274, A4: 3ffffa98, A5: 00000000, A6: 000008ff, A7: 00000200, A8: 0007bb49, A9: 000f4240, A10: 00000001, A11: 04444444, A12: 8008376e, A13: 3ffff750, A14: 00000000, A15: 10040000, SAR: 00000010, EXCCAUSE: 0000001c, EXCVADDR: 00000001, LBEG: 40079161, LEND: 40079168, LCOUNT: 00000000, THREADPTR: 00000000, SCOMPARE1: 00000000, BR: 00000000, ACCLO: 00000000, ACCHI: 00000000, M0: 00000000, M1: 00000000, M2: 00000000, M3: 00000000, F64R_LO: 00000000, F64R_HI: 00000000, F64S: 00000000, FCR: 00000000, FSR: 00000000, F0: 00000000, F1: 00000000, F2: 00000000, F3: 00000000, F4: 00000000, F5: 00000000, F6: 00000000, F7: 00000000, F8: 00000000, F9: 00000000, F10: 00000000, F11: 00000000, F12: 00000000, F13: 00000000, F14: 00000000, F15: 00000000, reserved: [00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 800da2f0], BASESAVE: [3ffffaa0, 00000001, 3fffff78, 00000000] }), location: Location { file: "/Users/bquentin/oss/esp/xtensa-lx-rt/src/exception/lx6.rs", line: 95, col: 5 } }
The assembly looks like this:
fn wait() {
400d9760: 006136 entry a1, 48
400d9763: 080c movi.n a8, 0
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:180
let mut c: i32 = 0;
400d9765: 2189 s32i.n a8, a1, 8
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:181
loop {
400d9767: ffffc6 j 400d976a <timer::wait+0xa>
400d976a: 08c1a2 addi a10, a1, 8
400d976d: dbcfb1 l32r a11, 400d06ac <_stext+0x68c>
400d9770: dbd081 l32r a8, 400d06b0 <_stext+0x690>
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:182
let is_lower = lower(&c, &1_000_000);
400d9773: 0008e0 callx8 a8
400d9776: 0a8d mov.n a8, a10
400d9778: 1189 s32i.n a8, a1, 4
400d977a: 0c41a2 s8i a10, a1, 12
400d977d: ffffc6 j 400d9780 <timer::wait+0x20>
400d9780: 1188 l32i.n a8, a1, 4
400d9782: 190c movi.n a9, 1
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:183
if !is_lower {
400d9784: 108890 and a8, a8, a9
400d9787: 00e816 beqz a8, 400d9799 <timer::wait+0x39>
400d978a: ffffc6 j 400d978d <timer::wait+0x2d>
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:186
break;
} else {
c += 1;
400d978d: 2198 l32i.n a9, a1, 8
400d978f: 891b addi.n a8, a9, 1
400d9791: 0189 s32i.n a8, a1, 0
400d9793: 0b2897 blt a8, a9, 400d97a2 <timer::wait+0x42>
400d9796: 000046 j 400d979b <timer::wait+0x3b>
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:189
}
}
}
400d9799: f01d retw.n
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:186
c += 1;
400d979b: 0188 l32i.n a8, a1, 0
400d979d: 2189 s32i.n a8, a1, 8
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:181
loop {
400d979f: fff1c6 j 400d976a <timer::wait+0xa>
400d97a2: dbc4a1 l32r a10, 400d06b4 <_stext+0x694>
400d97a5: cb1c movi.n a11, 28
400d97a7: dbc4c1 l32r a12, 400d06b8 <_stext+0x698>
400d97aa: daee81 l32r a8, 400d0364 <_stext+0x344>
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:186
c += 1;
400d97ad: 0008e0 callx8 a8
400d97b0: 0041f0 break 1, 15
400f5364 <timer::lower>:
timer::lower:
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:191
fn lower(a: &i32, b: &i32) -> bool {
400f5364: 006136 entry a1, 48
400f5367: 2129 s32i.n a2, a1, 8
400f5369: 3139 s32i.n a3, a1, 12
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:192
*a < *b
400f536b: 0288 l32i.n a8, a2, 0
400f536d: 0398 l32i.n a9, a3, 0
400f536f: 0a0c movi.n a10, 0
400f5371: 01a9 s32i.n a10, a1, 0
400f5373: 1a0c movi.n a10, 1
400f5375: 11a9 s32i.n a10, a1, 4
400f5377: 032897 blt a8, a9, 400f537e <timer::lower+0x1a>
400f537a: 0188 l32i.n a8, a1, 0
400f537c: 1189 s32i.n a8, a1, 4
400f537e: 1128 l32i.n a2, a1, 4
/Users/bquentin/oss/esp/esp32-hal/examples/timer.rs:193
}
400f5380: f01d retw.n
At 0x400d06ac there is the address of the value 1_000_000.
At 0x400d06b0 there is the address of the to_lower
function
If I understand everything correct here, the generated code doesn't look really wrong
I experienced an interesting crash which doesn't originates in the HAL code but since it's easy to explain how to reproduce it here, I post it in this repository. Since I don't know what really causes the problem, I don't know a much better place to report this anyway.
Actually, I experienced this when doing something without the HAL
To reproduce it just take the
timer.rs
example and replace https://github.com/esp-rs/esp32-hal/blob/17e9fd7cfa7bc675eba4f06e7a7b59ccc8910330/examples/timer.rs#L174 with a busy loop likefor _ in 0..100_000 {}
With that change I quickly get an exception like this
*** PanicInfo { payload: Any { .. }, message: Some(Exception: StoreProhibited, Context { PC: 400f4699, PS: 00060f30, A0: 800d9332, A1: 3ffff9c0, A2: 00000001, A3: 000108ec, A4: 8008376e, A5: 3ffff6e0, A6: 00000000, A7: 10040000, A8: 000108ec, A9: 01010101, A10: 0f0f0f0f, A11: 04444444, A12: 8008376e, A13: 3ffff6a0, A14: 00000000, A15: 10200000, SAR: 00000010, EXCCAUSE: 0000001d, EXCVADDR: 00000001, LBEG: 40079161, LEND: 40079168, LCOUNT: 00000000, THREADPTR: 00000000, SCOMPARE1: 00000000, BR: 00000000, ACCLO: 00000000, ACCHI: 00000000, M0: 00000000, M1: 00000000, M2: 00000000, M3: 00000000, F64R_LO: 00000000, F64R_HI: 00000000, F64S: 00000000, FCR: 00000000, FSR: 00000000, F0: 00000000, F1: 00000000, F2: 00000000, F3: 00000000, F4: 00000000, F5: 00000000, F6: 00000000, F7: 00000000, F8: 00000000, F9: 00000000, F10: 00000000, F11: 00000000, F12: 00000000, F13: 00000000, F14: 00000000, F15: 00000000, reserved: [00000000, 00000000, 00000000, 00000000, 00000000, 00000000, 800d9580], BASESAVE: [3ffff9f0, 3fffff78, 000108ec, 000108ec] }), location: Location { file: "/Users/bquentin/.cargo/registry/src/github.com-1ecc6299db9ec823/xtensa-lx-rt-0.7.0/src/exception/lx6.rs", line: 95, col: 5 } }
Changing the ESP-Rust toolchain to e.g. 1.56.0.1 doesn't change anything. Also, in release mode (certainly the busy loop needs modification to prevent it from getting optimized away) it's the same.
No idea yet what is causing this. As said, it's definitely not the HAL since I first experienced this without the HAL.
I used a generic ESP32 dev-board but I doubt it makes a difference.
Maybe @MabezDev has an idea where to look?