rust-embedded / cortex-m-rt

Minimal startup / runtime for Cortex-M microcontrollers
https://rust-embedded.github.io/cortex-m-rt/
Apache License 2.0
359 stars 85 forks source link

Add force-setting of stack pointer in startup code #254

Closed korken89 closed 3 years ago

korken89 commented 4 years ago

During experimenting with new unsafe code I realized that the stack pointer can easily be corrupted, and this can propagate and stick after a system reset while having a debugger connected. This causes preinit to automatically hardfault if using the stack and the zeroing/init of RAM under no optimization also directly hardfaults.

I propose we add the code to always hard-load the stack pointer from the vector table. It will cost a few bytes, but I argue that it is a price worth to pay to have stable debug/implementation runs. Currently it is trivial to get into a very hard to debug state.

jonas-schievink commented 4 years ago

How/Why does this situation happen, exactly? I wouldn't want to work around issues we don't fully understand in cmrt.

adamgreig commented 4 years ago

The architecture reference manuals seem pretty explicit that SP is always initialised from the vector table on any power-on or reset, with no mention of exceptions, so something definitely seems wrong here. Do you have a short reproducible example?

korken89 commented 4 years ago

Sadly I'm far gone from this issue right now, but I'll look into reproducing it. The issue is not on the Cortex-M core or the reset itself though, it's the debuggers. It seems some do not implement reset correctly, for example the stlinkv2, which after reset mon reset halt had the old stack pointer in some cases (especially after HardFault).

jonas-schievink commented 3 years ago

I believe we discussed this at some point (or a similar issue) and concluded that this is a bug in the debugger that we don't really want to work around at this point, so closing this.