It's something the compiler decides. The debugger just "reacts".
(Not tested, but...) Have you tried with -O- ? No optimization at all. Even -O1 could cause stuff like this.
(At leat on Win...) In the same way, the compiler adds the info that some of the code in the final "end;" of a procedure is in the "begin" line. Hence the debugger jumps around.
The fact that it jumps several times, is because it "steps over" the internal "finally" block that fpc added (and finally is a subroutine). That (the several times jumping around) is something that should be fixable in the debugger (in FpDebug).