Why does Power Down not work here?

#include <avr/sleep.h>

void setup(){
  // disable ADC
  ADCSRA = 0;  
  pinMode(2,INPUT);
  attachInterrupt (0, gotoSleep, RISING);
  Serial.begin(9600);
  Serial.println("reset");
}

void loop(){

  
}

void gotoSleep(){
  Serial.println("gotoSleep");
  detachInterrupt (0);
  attachInterrupt (0, wake, RISING);
  set_sleep_mode (SLEEP_MODE_IDLE);  
  sleep_enable();
  sleep_cpu (); 
 detachInterrupt (0); 
 attachInterrupt (0, gotoSleep, RISING);
}

void wake(){
  Serial.println("wake");
  sleep_disable();
}

This simply doesn't work for me and I don't know why. After "reset", serial wont print anything. I have a multimeter hooked up to it so I know it's not going to sleep. I can get it to sleep fine if I put the sleep stuff in the setup. But if I comment out all of the sleep and interrupt lines in the gotoSleep function, it calls gotoSleep just fine when I press the button.

I must be missing something very obvious.

You can't do Serial.print() in an ISR. Serial output requires interrupts, which are disabled in an ISR.

Both of your ISRs have Serial.print() statements. They have to go.

Ah, ok my problem first was that I didn't realize I was using "IDLE" so I wasn't getting the multimeter readings I was expecting. Then I added the serial out to double check and like you said, that doesn't work. I changed it to power down and everything it behaving now. Thanks.

I'd do Serial.flush() and Serial.end() before sleeping, and Serial.begin() after waking up.