暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

linux内核-coredump的触发机制

watson 2024-09-22
276

在之前的文章中,我们大致说明了coredump的生成机制,也就是coredump文件的生成流程。

但是实际上,这个流程并不是coredump独用,而是一套通用流程。图片在这个流程中,有信号产生方、信号存储方、信号消费方。

在这三个阶段,其中信号和中断有类似的地方,但是二者并不等价。

信号本质上是在软件层次上对中断机制的一种模拟,其主要有以下几种来源:

  • 程序错误:除零,非法内存访问等。
  • 外部信号:终端 Ctrl-C 产生 SGINT 信号,定时器到期产生SIGALRM等
  • 显式请求:kill函数允许进程发送任何信号给其他进程或进程组。
图片
图片

信号如何被接收的在今天这篇文章并不做介绍,只对信号存储和消费两部分进行说明。

图片

首先每个进程的结构体里都有信号的信息存储:

struct task_struct {
    ...
    int sigpending;
    ...
    struct signal_struct *sig;
    sigset_t blocked;
    struct sigpending pending;
    ...
}

sigpending 表示进程是否有信号需要处理(1表示有,0表示没有);成员 blocked 表示被屏蔽的信息,每个位代表一个被屏蔽的信号;成员 sig 表示信号相应的处理方法,其类型是 struct signal_struct。

在进程从用户态陷入内核态时,内核态完成了相关工作之后,返回用户态之前,都会例行对进程的信号队列进行检查。

这段逻辑是汇编实现的,因为在linux内核中,用户态的切换就是汇编来控制的。【可能有同学对用户态和内核态的切换不太了解,其实用大白话讲就是,只是对cpu的寄存器的赋值进行更换,跟普通的进程切换可能没什么区别,但是同时又有区别,因为用户态和内核态的堆栈是分离开的,这样二者在切换的时候是需要在两个堆栈上进行操作,并且保存上下文信息】

图片
图片
ENTRY(ret_from_sys_call)
 ...
ret_with_reschedule:
 ...
 cmpl $0, sigpending(%ebx)  // 检查进程的sigpending成员是否等于1
 jne signal_return          // 如果是就跳转到 signal_return 处执行
restore_all:
 RESTORE_ALL

 ALIGN
signal_return:
 sti                             // 开启硬件中断
 testl $(VM_MASK),EFLAGS(%esp)
 movl %esp,%eax
 jne v86_signal_return
 xorl %edx,%edx
 call SYMBOL_NAME(do_signal)    // 调用do_signal()函数进行处理
 jmp restore_all

图片可以看到在内核代码中,指定了哪些信号可以产生dump core文件

后续就是对linux的信号处理机制方面进行深究和学习。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论