chore(intr): 探针补记被中断代码的 RIP/CS/RSP,用于定位卡死线程停在哪条指令

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 表示卡在内核。
This commit is contained in:
TermiNexus committed 2026-10-16 17:58:51 +08:00
1 parent 2784b327c7
commit c29c1953df
2 files changed
+31 -1

No files matched your search

+15
View File
@@ -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
+16 -1
View File
@@ -26,7 +26,9 @@ static timer_running: volatile bool = False
# C) 探针继续、cur 在变 → 调度器活着,问题在桌面线程自身
#
# 直接写 COM1 0x3F8(自带 LSR 超时,绝不依赖 serial 驱动、绝不挂住 ISR)。
# 每行格式:`[t] <ticks:8hex> <current_tid:8hex> <thread_count:8hex> <每个线程 state 的 1 位 hex>`
# 每行格式(`_intr_*` 由 isr.s 在每次中断入口写入 = 最后一次定时中断打断的那条指令):
# `[t] <ticks:8hex> <current_tid:8hex> <thread_count:8hex> <各线程 state 1 位hex> <intr_rip:8hex> <intr_cs:8hex> <intr_rsp:8hex>`
# 卡死线程的现场就是 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():