Imho, level2 optimizations are still - as documented - debugger friendly, but higher optimizations can - as documented - have side effects and that is in some cases an issue.
Level 2 optimizations can already lead to code that might lead to issues in the debugger, but don't have side effects. E.g. the REGVAR optimization might be enabled there which can lead to less stack usage or reuse of the same register for different variables without the variable being stored anywhere if the lifetime permits it. After all Lazarus only declares -O1 as more or less debugger friendly for a reason...
Indeed.
Level 2 opts provide still mostly intact line-info. Of course
- inlined code can't be stepped, or have breakpoints
- break, exit statements may merge with the line before them (though that happens in level 1 already), but level 2 may optimize more lines away
But, as for variables, values can't be trusted much (well at least not local vars). If they are not in registers, they may still delay updating their memory. So the value may show only once stepped an extra line away.
But if they are in registers, they show the value of that register, regardless if it currently is that value. That is, a single register is often used for several vars (in different lines of code), yet the compiler just says "variable foo is in reg x" as if for the whole time.