@@ -441,6 +441,15 @@ void thread_switch(tcb_t *thr)
441441 assert ((intptr_t ) thr );
442442 assert (thread_isrunnable (thr ));
443443
444+ /* Check stack canary before switching to this thread.
445+ * If canary is corrupted, the thread's stack has overflowed.
446+ */
447+ if (!thread_check_canary (thr )) {
448+ panic ("Stack overflow: tid=%t, stack_base=%p, canary=%p\n" ,
449+ thr -> t_globalid , thr -> stack_base ,
450+ thr -> stack_base ? * ((uint32_t * ) thr -> stack_base ) : 0 );
451+ }
452+
444453 current = thr ;
445454 current_utcb = thr -> utcb ;
446455 if (current -> as )
@@ -528,4 +537,39 @@ void kdb_dump_threads(void)
528537 }
529538}
530539
540+ void kdb_dump_stacks (void )
541+ {
542+ tcb_t * thr ;
543+ int idx ;
544+
545+ dbg_printf (DL_KDB , "%5s %8s %10s %10s %10s %6s\n" ,
546+ "type" , "global" , "stack_base" , "stack_size" , "sp" , "canary" );
547+
548+ for_each_in_ktable (thr , idx , (& thread_table )) {
549+ char * canary_status ;
550+ uint32_t canary_val = 0 ;
551+
552+ if (!thr -> stack_base ) {
553+ canary_status = "N/A" ;
554+ } else {
555+ canary_val = * ((uint32_t * ) thr -> stack_base );
556+ canary_status = (canary_val == STACK_CANARY ) ? "OK" : "FAIL" ;
557+ }
558+
559+ dbg_printf (DL_KDB , "%5s %t %p %10d %p %6s\n" ,
560+ kdb_get_thread_type (thr ),
561+ thr -> t_globalid ,
562+ thr -> stack_base ,
563+ thr -> stack_size ,
564+ thr -> ctx .sp ,
565+ canary_status );
566+
567+ /* If canary failed, show what was found */
568+ if (thr -> stack_base && canary_val != STACK_CANARY ) {
569+ dbg_printf (DL_KDB , " expected: %p, found: %p\n" ,
570+ STACK_CANARY , canary_val );
571+ }
572+ }
573+ }
574+
531575#endif /* CONFIG_KDB */
0 commit comments