{"record":{"id":"05c15a014868f7d1","repo":"embassy-rs/embassy","slug":"interruptexecutor-start-called-multiple-times-o","errorCode":null,"errorMessage":"InterruptExecutor::start() called multiple times on the same executor.","messagePattern":"InterruptExecutor::start\\(\\) called multiple times on the same executor\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-executor/src/platform/aarch32.rs","lineNumber":269,"sourceCode":"        /// You must set the interrupt priority (in `GICD_IPRIORITYR`) before calling this method.\n        /// You MUST NOT do it after.\n        ///\n        /// The SGI may be configured as either Group 0 or Group 1 in `GICD_IGROUPR0`. You must\n        /// configure the group before calling this method, you MUST NOT change it after.\n        ///\n        /// The SGI is always sent to the CPU that pends it, so on multi-core chips the executor\n        /// must only be woken from the core it was started on.\n        ///\n        /// # Panics\n        ///\n        /// Panics if `sgi_id` is greater than 15, or if the executor was already started.\n        ///\n        /// [`SendSpawner`]: crate::SendSpawner\n        pub fn start(&'static self, gicd_base: usize, sgi_id: u8) -> crate::SendSpawner {\n            assert!(sgi_id < 16, \"SGI interrupt ID must be in the range 0..=15\");\n\n            if critical_section::with(|cs| self.started.borrow(cs).replace(true)) {\n                panic!(\"InterruptExecutor::start() called multiple times on the same executor.\");\n            }\n\n            let inner = unsafe {\n                let inner = (*self.inner.get()).as_mut_ptr();\n                // Initialize the target first: the executor's pender context points to it.\n                (&raw mut (*inner).target).write(SgiTarget::new(gicd_base, sgi_id));\n                let target = &raw const (*inner).target;\n                (&raw mut (*inner).executor).write(raw::Executor::new(target as *mut ()));\n                &*inner\n            };\n\n            inner.target.enable();\n\n            inner.executor.spawner().make_send()\n        }\n\n        /// Get a SendSpawner for this executor\n        ///","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-executor/src/platform/aarch32.rs#L251-L287","documentation":"Panic raised by the aarch32 InterruptExecutor::start implementation's internal state guard. Each interrupt executor can be started exactly once: start() writes the raw executor state into the static slot and enables the software-generated interrupt. A second call would overwrite partially-initialized state and re-arm the SGI, corrupting the running executor. This fires when application or platform init code calls start() on the same 'static executor instance twice, typically from duplicated board-init paths or a restarted module.","triggerScenarios":"Thrown at embassy-executor/src/platform/aarch32.rs:269 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Call InterruptExecutor::start() exactly once per executor instance, at a single well-known init point","Guard the start call with an application-level 'initialized' flag or OnceCell so repeated init paths are idempotent","If restart is required, create a new static executor instance instead of re-starting the existing one","Audit board startup code so the executor is not started from both main and a secondary-core or reset path"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}