From c29c1953df03c057c071c2ae7b7ce46aec2ab8d8 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 16 Oct 2026 17:58:51 +0800 Subject: [PATCH] =?UTF-8?q?chore(intr):=20=E6=8E=A2=E9=92=88=E8=A1=A5?= =?UTF-8?q?=E8=AE=B0=E8=A2=AB=E4=B8=AD=E6=96=AD=E4=BB=A3=E7=A0=81=E7=9A=84?= =?UTF-8?q?=20RIP/CS/RSP=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=AE=9A=E4=BD=8D?= =?UTF-8?q?=E5=8D=A1=E6=AD=BB=E7=BA=BF=E7=A8=8B=E5=81=9C=E5=9C=A8=E5=93=AA?= =?UTF-8?q?=E6=9D=A1=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit isr.s: ISR_NOERR/ISR_ERR 的 _frame_ready 里把 r8(RIP)/r9(CS)/rax(RSP) 写进新增的 _intr_rip/_intr_cs/_intr_rsp(只读这三个寄存器,不影响随后压栈)。timer.vp: 心跳行追加 3 个 hex32 字段。定时器 1kHz,所以这三个值几乎总是最后一次定时中断打断的现场:intr_cs=2B 表示该线程卡在用户态 intr_rip 处,=08 表示卡在内核。 --- VKernel/Kernel/intr/isr.s | 15 +++++++++++++++ VKernel/Kernel/platform/pch/timer.vp | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/VKernel/Kernel/intr/isr.s b/VKernel/Kernel/intr/isr.s index 98853e8..e2d48d9 100644 --- a/VKernel/Kernel/intr/isr.s +++ b/VKernel/Kernel/intr/isr.s @@ -15,6 +15,13 @@ # (读 RIP/CS/RFLAGS、算 is_user),若不保存就会破坏被中断代码在这些寄存器里的 # 活跃值 → 概率性内存破坏/异常。出口(iretq 前)恢复。 .comm _isr_scratch, 48, 8 +# 【诊断·临时,定位后必须删除】被中断代码的 RIP/CS/RSP。ASR_NOERR/ISR_ERR 在 +# _frame_ready 里写入(此时 r8=RIP / r9=CS / rax=RSP / r11=SS)。timer.vp 的心跳 +# 探针读它们,用来定位"某个线程卡在用户态哪条指令上"。定时器 1kHz 触发,所以这三个 +# 值几乎总是最后一次定时中断的现场。 +.comm _intr_rip, 8, 8 +.comm _intr_cs, 8, 8 +.comm _intr_rsp, 8, 8 .section .text .intel_syntax noprefix @@ -106,6 +113,10 @@ isr\num\()_from_user: isr\num\()_frame_ready: # r8=RIP, r9=CS, r10=RFLAGS, rax=RSP(0 if kernel), r11=SS(0 if kernel) + # 【诊断·临时】记下被中断代码的 RIP/CS/RSP(只读 r8/r9/rax,不破坏后面要压栈的值) + mov [_intr_rip], r8 + mov [_intr_cs], r9 + mov [_intr_rsp], rax # Build uniform frame on stack for iretq later push r11 # SS push rax # RSP @@ -304,6 +315,10 @@ isr\num\()_from_user: isr\num\()_frame_ready: # rdx=error_code, r8=RIP, r9=CS, r10=RFLAGS, rax=RSP, r11=SS + # 【诊断·临时】同 ISR_NOERR:记下被中断代码的 RIP/CS/RSP + mov [_intr_rip], r8 + mov [_intr_cs], r9 + mov [_intr_rsp], rax # Build uniform frame on stack push r11 # SS push rax # RSP diff --git a/VKernel/Kernel/platform/pch/timer.vp b/VKernel/Kernel/platform/pch/timer.vp index 6504d67..51e9b7f 100644 --- a/VKernel/Kernel/platform/pch/timer.vp +++ b/VKernel/Kernel/platform/pch/timer.vp @@ -26,7 +26,9 @@ static timer_running: volatile bool = False # C) 探针继续、cur 在变 → 调度器活着,问题在桌面线程自身 # # 直接写 COM1 0x3F8(自带 LSR 超时,绝不依赖 serial 驱动、绝不挂住 ISR)。 -# 每行格式:`[t] <每个线程 state 的 1 位 hex>` +# 每行格式(`_intr_*` 由 isr.s 在每次中断入口写入 = 最后一次定时中断打断的那条指令): +# `[t] <各线程 state 1 位hex> ` +# 卡死线程的现场就是 intr_rip/intr_cs:cs=2B 表示卡在用户态该 rip 处,cs=08 表示卡在内核。 # ============================================================================ _dbg_tick: uint64 = 0 @@ -68,6 +70,19 @@ def _dbg_snapshot(): _dbg_putc(uint8(48 + st)) else: _dbg_putc(uint8(55 + st)) + # 被中断代码的 RIP/CS/RSP(isr.s 写入 _intr_*)——定位"卡在哪条指令"的关键。 + ir: uint64 = 0 + ic: uint64 = 0 + iu: uint64 = 0 + __asm__(f"mov {asmout(ir, ASM_DESCR.OUTPUT_REG)}, [_intr_rip]", op=[ASM_DESCR.CLOBBER_MEMORY]) + __asm__(f"mov {asmout(ic, ASM_DESCR.OUTPUT_REG)}, [_intr_cs]", op=[ASM_DESCR.CLOBBER_MEMORY]) + __asm__(f"mov {asmout(iu, ASM_DESCR.OUTPUT_REG)}, [_intr_rsp]", op=[ASM_DESCR.CLOBBER_MEMORY]) + _dbg_putc(uint8(32)) + _dbg_hex32(ir) + _dbg_putc(uint8(32)) + _dbg_hex32(ic) + _dbg_putc(uint8(32)) + _dbg_hex32(iu) _dbg_putc(uint8(10)) def timer_init():