I think it's clear you have a stack corruption somewhere. Making variables static is what I call a "hackers fix", it might get past the immediate corruption, but doesn't fix the underlying cause. Stack corruption could also be caused if stack overflows into other region.
The hardfault just shows the after effects of the corruption unfortunately, the registers will mostly be garbage. Clearly if you have a PC that is a RAM address then it has gone badly wrong. (You may have some code in RAM, but it should be easy to identify if it is valid for the PC to be in RAM or not from the link map).
The registers end up with garbage because a function call attempted to return and restored registers of a corrupted stack. The only useful register is LR, which is where the fault came from. You will need to trace back by setting breakpoints to find the function which did the restore. Hopefully, the corruption is in that function, but often there is some other function call that causes the corruption (could be an ISR).
So its a question of tracing through from before the corruption to narrow down the offending code. If you have a number of ways to repeatably create the fault that is good, I would start with the low optimisation version.