@@ -4,6 +4,8 @@ static symbol_t* symbol_table = NULL;
44uint32_t trace_thread_id = 0 ;
55static bool debug_signal = false;
66
7+ #define BT_IRQ_MARKER ((void*)0xFFFFffffFFFFff01ull)
8+
79volatile struct limine_module_request module_request = {
810 .id = LIMINE_MODULE_REQUEST ,
911 .revision = 0 ,
@@ -427,27 +429,87 @@ uint64_t findsymbol_addr(const char *name) {
427429 return 0 ;
428430}
429431
432+ static inline void get_kstack_bounds (uintptr_t * lo , uintptr_t * hi ) {
433+ uintptr_t rsp ;
434+ __asm__ volatile ("movq %%rsp,%0" : "=r" (rsp ));
435+ uintptr_t base = rsp & KSTACK_MASK ; /* aligned base for *this* CPU’s stack */
436+ * lo = base ;
437+ * hi = base + KSTACK_SIZE ; /* top (one-past) */
438+ }
430439
431- void backtrace ()
432- {
440+ static size_t count_markers_ahead (const stack_frame_t * frame , uintptr_t lo , uintptr_t hi , size_t probe ) {
441+ size_t cnt = 0 ;
442+ while (frame && CANONICAL_ADDRESS (frame ) && (uintptr_t )frame >= lo && (uintptr_t )frame <= (hi - sizeof (* frame )) && probe ++ < 1024 ) {
443+ const stack_frame_t * next = frame -> next ;
444+ if (next && (uintptr_t )next <= (uintptr_t )frame ) {
445+ break ; /* corrupted or cyclic chain */
446+ }
447+ if (frame -> addr == BT_IRQ_MARKER ) {
448+ cnt ++ ;
449+ }
450+ frame = next ;
451+ }
452+ return cnt ;
453+ }
454+
455+ void backtrace (void ) {
433456 stack_frame_t * frame ;
434457 __asm__ volatile ("movq %%rbp,%0" : "=r" (frame ));
435- uint64_t page = (uint64_t ) frame & 0xFFFFFFFFFFFFF000ull ;
436- uint64_t offset = 0 ;
437- const char * name = NULL ;
438458
439- /* Stack frame loop inspired by AlexExtreme's stack trace in Exclaim */
459+ uintptr_t lo , hi ;
460+ size_t depth = 0 ;
461+ get_kstack_bounds (& lo , & hi );
462+
463+ /* We know we’re in an ISR/exception at the top */
464+ setforeground (COLOUR_LIGHTYELLOW );
465+ kprintf ("--------------------------------[ IRQ/TRAP CONTEXT ]--------------------------------\n" );
466+ dprintf ("--------------------------------[ IRQ/TRAP CONTEXT ]--------------------------------\n" );
467+
468+ /* How many sentinels remain in this chain? (there is at least one) */
469+ size_t remaining_markers = count_markers_ahead (frame , lo , hi , depth );
470+
440471 setforeground (COLOUR_LIGHTGREEN );
441- while (frame && ((uint64_t )frame & 0xFFFFFFFFFFFFF000ull ) == page ) {
442- name = findsymbol ((uint64_t )frame -> addr , & offset );
472+ while (frame && CANONICAL_ADDRESS (frame ) && (uintptr_t )frame >= lo && (uintptr_t )frame <= (hi - sizeof (* frame )) && depth ++ < 1024 ) {
473+
474+ stack_frame_t * next = frame -> next ;
475+
476+ if (next && (uintptr_t )next <= (uintptr_t )frame ) {
477+ break ; /* corrupted or cyclic chain */
478+ }
479+
480+ if (frame -> addr == BT_IRQ_MARKER ) {
481+ /* Crossing this boundary */
482+ if (remaining_markers > 0 ) {
483+ remaining_markers -- ; /* consume this marker */
484+ }
485+ setforeground (COLOUR_LIGHTYELLOW );
486+ if (remaining_markers > 0 ) {
487+ kprintf ("--------------------------------[ IRQ/TRAP CONTEXT ]--------------------------------\n" );
488+ dprintf ("--------------------------------[ IRQ/TRAP CONTEXT ]--------------------------------\n" );
489+ } else {
490+ kprintf ("-------------------------------[ PRE-EMPTED CONTEXT ]-------------------------------\n" );
491+ dprintf ("-------------------------------[ PRE-EMPTED CONTEXT ]-------------------------------\n" );
492+ }
493+ setforeground (COLOUR_LIGHTGREEN );
494+
495+ frame = next ;
496+ continue ;
497+ }
498+
499+ uint64_t offset = 0 ;
500+ const char * name = findsymbol ((uint64_t )frame -> addr , & offset );
443501 if (!name || (strcmp (name , "pci_enable_msi" ) != 0 && strcmp (name , "vprintf" ) != 0 && strcmp (name , "printf" ) != 0 )) {
444- kprintf ("\tat %s()+0%08lx [0x%lx]\n" , name ? name : "[???]" , offset , (uint64_t )frame -> addr );
502+ kprintf ("\tat %s()+0%08lx [0x%lx]\n" , name ? name : "[???]" , offset , (uint64_t )frame -> addr );
503+ dprintf ("\tat %s()+0%08lx [0x%lx]\n" , name ? name : "[???]" , offset , (uint64_t )frame -> addr );
445504 }
446- frame = frame -> next ;
505+
506+ frame = next ;
447507 }
508+
448509 setforeground (COLOUR_WHITE );
449510}
450511
512+
451513uint32_t gdb_trace (const char * str ) {
452514 uint32_t hash = 5381 ;
453515 uint8_t c ;
0 commit comments