云计算百科
云计算领域专业知识百科平台

fault show_signal_msg

show_signal_msg 是 x86 架构缺页异常处理中,专门用于向内核日志打印“用户态致命段错误”诊断信息的静态内联函数。

它只在用户态程序触发了无法修复的页错误(如访问了非法地址),且内核需要向其发送 SIGSEGV 信号时被调用,目的是在系统日志中留下清晰的“犯罪现场”记录,方便开发者事后分析。

核心功能与逻辑

该函数的核心逻辑是条件性地打印一段标准格式的日志。其典型实现如下:

static inline void
show_signal_msg(struct pt_regs *regs, unsigned long error_code,
unsigned long address, struct task_struct *tsk)
{
const char *loglvl = task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG;

if (!unhandled_signal(tsk, SIGSEGV))
return;

if (!printk_ratelimit())
return;

printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx",
loglvl, tsk->comm, task_pid_nr(tsk), address,
(void *)regs->ip, (void *)regs->sp, error_code);

print_vma_addr(KERN_CONT " in ", regs->ip);
printk(KERN_CONT "\\n");
}

其执行流程包含两层过滤:

  • 信号处理检查:unhandled_signal(tsk, SIGSEGV) 确保只有未被用户程序捕获处理的段错误才会被打印。如果程序自己注册了 SIGSEGV 处理函数,内核就不会刷日志。

  • 频率限制:printk_ratelimit() 防止一个疯狂出错的程序在短时间内用海量日志刷爆内核缓冲区。

  • 日志格式与字段含义

    打印出的日志是内核调试的经典格式,例如:
    gnome-power-man[24509]: segfault at 20 ip 00007f9d4950465a sp 00007fffbb50fc70 error 4 in libgobject-2.0.so.0.2103.0[7f9d494f7000+45000]

    • gnome-power-man[24509]:进程名(comm)和 PID。

    • segfault at 20:触发错误的虚拟地址(address)。

    • ip 00007f9d…:出错时的指令指针(regs->ip),指向触发错误的用户态指令地址。

    • sp 00007fff…:出错时的栈指针(regs->sp)。

    • error 4:硬件错误码。4 通常表示用户态(bit 2)的读操作(bit 0 未置位)触发了页不存在错误(bit 1 未置位)。

    • in libgobject…:由 print_vma_addr 打印,指出 ip 落在哪个内存映射区域(如动态库),极大地帮助定位问题。

    关键设计细节

    • 日志级别选择:loglvl 会根据进程 PID 动态选择。对于 PID 1(init 进程),使用 KERN_EMERG 以确保即使日志系统未完全就绪也能输出;对于普通进程,使用 KERN_INFO。

    • CPU 信息扩展:后续补丁曾尝试在日志末尾添加 likely on CPU %d 信息,用于辅助识别硬件故障。但由于故障发生时进程可能被迁移,打印的 CPU 号是“可能”的而非绝对准确。

    • unhandled_signal 的过滤:这解释了为什么有些程序崩溃时你在 dmesg 里看不到 “segfault” 日志——因为该程序自己处理了 SIGSEGV 信号。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » fault show_signal_msg
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!