diff --git a/apps/main.c b/apps/main.c index dbfd2dc383..dd41559328 100644 --- a/apps/main.c +++ b/apps/main.c @@ -127,6 +127,10 @@ static void init(void); #ifdef SIMULATOR void app_main(void) #else +/* main(), and various functions called by main() and init() may be + * be INIT_ATTR. These functions must not be called after the final call + * to root_menu() at the end of main() + * see definition of INIT_ATTR in config.h */ int main(void) INIT_ATTR __attribute__((noreturn)); int main(void) #endif @@ -161,6 +165,8 @@ int main(void) #endif /* #ifdef AUTOROCK */ global_status.last_volume_change = 0; + /* no calls INIT_ATTR functions after this point anymore! + * see definition of INIT_ATTR in config.h */ root_menu(); } diff --git a/firmware/export/config.h b/firmware/export/config.h index ef72784ff7..739a859c1d 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -748,6 +748,16 @@ Lyre prototype 1 */ #define STATICIRAM static #endif #if (defined(CPU_PP) || (CONFIG_CPU == AS3525)) && !defined(SIMULATOR) && !defined(BOOTLOADER) +/* Functions that have INIT_ATTR attached are NOT guaranteed to survive after + * root_menu() has been called. Their code may be overwritten by other data or + * code in order to save RAM, and references to them might point into + * zombie area. + * + * It is critical that you make sure these functions are only called before + * the final call to root_menu() (see apps/main.c) is called (i.e. basically + * only while main() runs), otherwise things may go wild, + * from crashes to freezes to exploding daps. + */ #define INIT_ATTR __attribute__ ((section(".init"))) #define HAVE_INIT_ATTR #else