@@ -207,6 +207,7 @@ typedef struct {
207207 coro_context_t * context ; /* Context buffer */
208208 void * stack_base ; /* Stack base address */
209209 size_t stack_size ; /* Stack size */
210+ uint64_t canary ; /* Stack overflow detection canary */
210211} coro_t ;
211212
212213/* Global state */
@@ -222,6 +223,9 @@ static struct {
222223/* Stack size for each hart coroutine (1MB - increased for complex execution) */
223224#define CORO_STACK_SIZE (1024 * 1024)
224225
226+ /* Stack canary value for overflow detection */
227+ #define STACK_CANARY_VALUE 0xDEADBEEFCAFEBABEULL
228+
225229/* Sentinel value for current_hart when no coroutine is running */
226230#define CORO_HART_ID_IDLE UINT32_MAX
227231
@@ -241,6 +245,19 @@ static inline void coro_clear_running_state(void)
241245 tls_running_coro = NULL ;
242246}
243247
248+ /* Check for stack overflow by verifying the canary value */
249+ static inline void coro_check_stack (coro_t * co )
250+ {
251+ if (co -> canary != STACK_CANARY_VALUE ) {
252+ fprintf (stderr ,
253+ "FATAL: Stack overflow detected in coroutine! "
254+ "Expected canary=0x%llx, got=0x%llx\n" ,
255+ (unsigned long long ) STACK_CANARY_VALUE ,
256+ (unsigned long long ) co -> canary );
257+ abort ();
258+ }
259+ }
260+
244261/* Forward declarations */
245262
246263#ifdef CORO_USE_ASM
@@ -483,6 +500,9 @@ bool coro_create_hart(uint32_t hart_id, void (*func)(void *), void *hart)
483500 return false;
484501 }
485502
503+ /* Initialize stack canary for overflow detection */
504+ co -> canary = STACK_CANARY_VALUE ;
505+
486506 /* Initialize context */
487507#ifdef CORO_USE_ASM
488508 make_context (co , & co -> context -> ctx , co -> stack_base , co -> stack_size );
@@ -520,9 +540,15 @@ void coro_resume_hart(uint32_t hart_id)
520540 return ;
521541 }
522542
543+ /* Check for stack overflow before resuming */
544+ coro_check_stack (co );
545+
523546 coro_state .current_hart = hart_id ;
524547 co -> state = CORO_STATE_RUNNING ;
525548 jump_into (co );
549+
550+ /* Check for stack overflow after returning from coroutine */
551+ coro_check_stack (co );
526552}
527553
528554void coro_yield (void )
0 commit comments