Compare match interrupt and Serial.print();

I want to have an interrupt that runs roughly 75 times a second to, among other things, handle some housekeeping and check for button presses.

As far as I can tell I have it set up correctly, but it always crashes at the same point:

RTI Fired @ 13
RTI Fired @ 26
RTI Fired @ 39
RTI Fired @ 53
RTI Fired @ 66
RTI Fired @ 79
RTI Fired @ 93
RTI Fired @ 106
RTI Fired @ 119
RTI Fired @ 133
RTI Fired @ 146
R

You can see it's firing roughly every 13ms as expected, then at around 159ms in it dies. I know it has to do with the Serial.print() routine conflicting with the interrupt, probably by being midprint when it fires again. If I up the baud rate to something like 57600 it runs fine. I understand why it dies where it does (outputting 15 characters @ 9600 baud takes ~13ms the same as the ISR fire rate).

I'd like to better understand what's going on and how to protect against it. This ISR will be running in a complex program and I need to ensure it won't cause other issues like this.

Here's the test code:

void setup()
{
  Serial.begin(9600);
  setupRTI();
}
void loop()
{
//nothing
}
void setupRTI()
{
  //Use timer 5, output A  (pin 44)
  // initialize timer5
  noInterrupts();           // disable all interrupts
  TCCR5A = 0;
  TCCR5B = 0;
  TCNT5  = 0;

  OCR5A = 833;            // compare match register 16MHz/256/75Hz ~75.03Hz 
  TCCR5B |= (1 << WGM12);   // CTC mode
  TCCR5B |= (1 << CS12);    // 256 prescaler 
  TIMSK5 |= (1 << OCIE5A);  // enable timer compare interrupt mask
  interrupts();             // enable all interrupts
}

ISR(TIMER5_COMPA_vect)          // timer compare ISR
{
  Serial.print("RTI Fired @ ");   //print RTI fire time
  Serial.println(millis());
}

I don't think I can use cli(); and sei(); since the serial routine would just enable interrupts anyway right?
Do I need to mask OCIE5A while critical things are running?

You're sending about 18 characters, 75 times per second.

18 * 75 = 1350 characters per second * 10 = 13,500 bits per second.

You are sending at 9,600 bits per second.

When the buffer fills the Serial routines wait for an interrupt to move a character out of the buffer... and interrupts are disabled so it will wait forever. It is generally not a good idea to use Serial.print() in an ISR.

Set your baudrate well above 13,500 and the code will last longer.

Perhaps the first 11 samples will be enough.

You were probably writing that while I edited my post, but I understand why the crash is happening. What I was asking is how to protect against it, assuming for some reason I HAVE to do a Serial.print() (or something else) inside an ISR that will take longer than the period of the interrupt.

Thanks

Edit: I suppose better practice would be to set a flag in the ISR, then check it in the main loop and do serial.prints from there.

assuming for some reason I HAVE to do a Serial.print() (or something else) inside an ISR that will take longer than the period of the interrupt.

See, that's the problem. We're not willing to assume that HAVE to do something you KNOW you shouldn't (and, realistically, can't) do.