My profiling code showed, that a simple Move (without path, just one direction) or Pickup can need 20ms. To execute the first line of the mainloop can need 120ms!
If you detect such high cpu usage at the beginning of the mainloop, then most likely all other operations would also be very slow. You might consider skipping that tick - or at least, just execute what's absolutely necessary. Otherwise it's wasting your cpu time in bucket with a timeout.
So, if it's not in your hand, you can find that out easily by looking up CPU-time at the beginning of the loop.
For other cases, I've found that Memory is saved even after a timeout! So you can write your current state/position into Memory all the time, removing it at the end of the loop. If your script was cancelled by timeout, you can fetch the last state/position from Memory the next tick.
However, it would be useful if the system would give us a stacktrace to lookup the last position before timeout.