正常
Lab 001 · POSIX 信号 验证
对应
document/book/14-process-advanced/001/。验证档 A 档(能 sigaction 捕获)+ B(投递内部)。验证靠构建 + 测试 + grep + handler 往返。
目标
确认四件事:
- 信号数据结构 + 投递三件套在(
signal_send/pick_deliverable/check_and_deliver); - Custom handler 走 ISR 路径(
signal_setup_frame建栈帧),sigreturn 经int $0x80; - 三处集成:PF→SIGSEGV(替代 042 的 exit_current)、exit→SIGCHLD、write→SIGPIPE;
- run-kernel-test 从 044 的 763 涨到 783。
步骤
1. 构建 + 测试
bash
git checkout 001_proc_signals 2>/dev/null || git checkout 001_*
cmake -B build -S . && cmake --build build -j$(nproc) > /tmp/b.log 2>&1; echo "build=$?"
cmake --build build --target run-kernel-test2. 数据结构 + 投递
bash
grep -rn 'signal_send\|signal_pick_deliverable\|signal_check_and_deliver\|signal_setup_frame' kernel/proc/signal.cpp
grep -rn 'sys_kill\|sys_rt_sigaction\|sys_rt_sigprocmask' kernel/syscall/sys_signal.hpp思考:为什么 Custom handler 不走 syscall 路径投递?——见章节:syscall.S 帧精简(无 R12-R15),sigreturn 没法完整恢复。Custom 走 ISR 返回路径建完整 SignalFrame,sigreturn 经 int $0x80 收完整 InterruptFrame。syscall 路径只投 Default/Ignore,Custom 留 pending 等下次 IRQ0。
3. PF→SIGSEGV(和 042 对照)
bash
grep -n 'SIGSEGV\|signal_send' kernel/arch/x86_64/exception_handlers.cpp对比 042:那里 user-fault no-VMA 是 exit_current 直接杀;001 改成 signal_send(SIGSEGV)+return,ISR 投递——能被 handler 捕获,或默认终止。这是 042→001 的行为演进。
4.(A 档)handler 往返 + sigreturn trampoline
bash
grep -n 'cd 80\|int .0x80\|trampoline' kernel/proc/signal.cpp去看 signal.cpp 里 sigreturn trampoline 的构造(栈上 cd 80+nop,handler 返回地址指它)。内核测试里 signal_setup_frame 构造 + sigreturn 恢复两条单测覆盖往返。思考:为什么这个 trampoline 是"登记好的债"?——见章节 GOTCHA#10:依赖栈可执行,NXE 未启用故可行;F9(056)启用 NXE 后栈不可执行,trampoline 失效,须迁 vdso。
验收清单
- [ ] 构建
build=0,run-kernel-test ~783。 - [ ]
signal_send/pick_deliverable/check_and_deliver/setup_frame+ kill/sigaction/sigprocmask 都在。 - [ ] PF→SIGSEGV 替代了 042 的 exit_current;exit→SIGCHLD、write→SIGPIPE 在。
- [ ] 能说清「Custom 为何走中断路径」「sigreturn trampoline 为何是债」。
别做这些
- 别在 syscall 路径投递 Custom——帧不全,sigreturn 恢复不全。
- 别忘了
signal_check_and_deliver_isr要判frame->cs&0x03——否则 kernel-test(ring0)被误投递,测试崩。 - 记着:F9 启用 NXE 后,sigreturn trampoline 必须迁 vdso(栈不可执行)。